web-dev-qa-db-de.com

Wie erstelle ich eine unveränderliche Liste in Java?

Ich muss ein veränderliches Listenobjekt in eine unveränderliche Liste konvertieren, was in Java möglich ist.

public void action() {
    List<MutableClass> mutableList = Arrays.asList(new MutableClass("san", "UK", 21), new MutableClass("peter", "US", 34));
    List<MutableClass> immutableList = immutateList(mutableList);
}

public List<MutableClass> immutateList(List<MutableClass> mutableList){
    //some code here to make this beanList immutable
    //ie. objects and size of beanList should not be change.
    //ie. we cant add new object here.
    //ie. we cant remove or change existing one.
}

MutableClass

final class MutableClass {
    final String name;    
    final String address;
    final int age;
    MutableClass(String name, String address, int age) {
        this.name = name;
        this.address = address;
        this.age = age;
    }
}
23
user4768611

Sobald Ihre beanList initialisiert wurde, können Sie dies tun

beanList = Collections.unmodifiableList(beanList);

um es unveränderlich zu machen. (Siehe unveränderliche vs. nicht veränderbare Sammlung )

Wenn Sie sowohl über interne Methoden verfügen, die in der Lage sein sollten, die Liste zu ändern, als auch über öffentliche Methoden, die keine Änderung zulassen, sollten Sie dies tun

// public facing method where clients should not be able to modify list    
public List<Bean> getImmutableList(int size) {
    return Collections.unmodifiableList(getMutableList(size));
}

// private internal method (to be used from main in your case)
private List<Bean> getMutableList(int size) {
    List<Bean> beanList = new ArrayList<Bean>();
    int i = 0;

    while(i < size) {
        Bean bean = new Bean("name" + i, "address" + i, i + 18);
        beanList.add(bean);
        i++;
    }
    return beanList;
}

(Ihre Bean-Objekte scheinen bereits unveränderlich zu sein.)


Als Randbemerkung: Wenn Sie Java 8+ verwenden, kann Ihre getMutableList wie folgt ausgedrückt werden:

return IntStream.range(0,  size)
                .mapToObj(i -> new Bean("name" + i, "address" + i, i + 18))
                .collect(Collectors.toCollection(ArrayList::new));
36
aioobe

Verwenden Sie Collections.unmodifiableList() . Sie übergeben Ihre ursprüngliche ArrayList und geben eine Liste zurück, die eine Ausnahme auslöst, wenn Sie versuchen, Elemente hinzuzufügen, zu entfernen oder zu verschieben. Verwenden Sie beispielsweise return Collections.unmodifiableList(beanList); anstelle von return beanList; am Ende von getImmutableList(). main() löst eine Ausnahme aus. Die Collections-Klasse verfügt über Methoden für alle anderen allgemeinen Auflistungstypen neben list.

7
Mad Physicist

In JDK 8:

List<String> stringList = Arrays.asList("a", "b", "c");
stringList = Collections.unmodifiableList(stringList);

In JDK 9:

List stringList = List.of("a", "b", "c");

Referenz

3
Roushan

Die nachstehende Lösung dient zum Erstellen einer Liste als unveränderlich ohne Verwendung einer API. 

Unveränderliches Objekt mit ArrayList-Membervariable

public final class Demo {

    private final List<String> list = new ArrayList<String>();

    public Demo() {
        list.add("A");
        list.add("B");
    }

    public List<String> getImmutableList() {
        List<String> finalList = new ArrayList<String>();
        list.forEach(s -> finalList.add(s));
        return finalList;
    }

    public static void main(String[] args) {
        Demo obj = new Demo();
        System.out.println(obj.getImmutableList());
        obj.getImmutableList().add("C");
        System.out.println(obj.getImmutableList());
    }
}

Die tatsächliche Liste ändert sich also nicht, es wird immer [A, B] ausgegeben.

Ab Java 10 kannList.copyOf(Collection)verwendet werden, um eine unveränderbare Liste aus der angegebenen Sammlung zurückzugeben. Aus dem Quellcode der List.copyOf-Methode:

  • wenn es sich bei der angegebenen Sammlung um eine nicht änderbare Liste handelt, erstellt List.copyOf() keine Kopie.

  • wenn die angegebene Sammlung veränderbar und geändert ist, werden diese Änderungen in der zurückgegebenen Liste nicht berücksichtigt. Das heißt, sie sind abhängig.

2
tonyhoan

Machen Sie es unveränderlich, anstatt direkt unmodifizableList on list zu verwenden, da sonst die ursprüngliche Liste geändert werden kann.

Grundsätzlich ist die nicht modifizierbare Sammlung eine Ansicht. Sie kann also indirekt von einer anderen Referenz, die modifizierbar ist, aus "modifiziert" werden. Wenn sich die Quellensammlung ändert, wird die nicht modifizierbare Sammlung immer mit den neuesten Werten angezeigt.

Die unveränderliche Sammlung kann jedoch als schreibgeschützte Kopie einer anderen Sammlung behandelt und nicht geändert werden. In diesem Fall spiegelt unveränderliche Sammlung die Änderungen nicht wider, wenn sich die Quellensammlung ändert

List<String> immutableList=Collections.unmodifiableList(
                            new ArrayList<String>(modifiableList));

Verwendung von Guave:

import Java.util.*; 
import com.google.common.collect.ImmutableList; 
ImmutableList<String> iList = ImmutableList.copyOf(list); 
1
Saurabh

Wenn Sie die Bibliothek eines Drittanbieters verwenden möchten, können Sie mit Eclipse Collection s von MutableList in ImmutableList und zurück konvertieren.

MutableList<String> mutable = Lists.mutable.with("a", "b", "c");
ImmutableList<String> immutable = mutable.toImmutable();
MutableList<String> mutableAgain = immutable.toList();

Dies funktioniert auch bei primitiven Sammlungen.

MutableCharList mutable = CharLists.mutable.with('a', 'b', 'c');
ImmutableCharList immutable = mutable.toImmutable();
MutableCharList mutableAgain = immutable.toList();

Wenn Sie eine ArrayList als veränderliche List haben, funktionieren die folgenden.

List<String> mutable = new ArrayList<>(Arrays.asList("a", "b", "c"));
ImmutableList<String> immutable = Lists.immutable.withAll(mutable);
List<String> mutableAgain = immutable.toList();

Hinweis: Ich bin ein Committer für Eclipse-Sammlungen.

1
Donald Raab