web-dev-qa-db-fra.com

Comment créer une liste immuable en Java?

Je dois convertir un objet de liste mutable en liste immuable, quelle est la méthode possible en Java.

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

Une fois que votre beanList a été initialisée, vous pouvez faire

beanList = Collections.unmodifiableList(beanList);

pour le rendre non modifiable. (Voir Collection immuable vs non modifiable )

Si vous avez à la fois des méthodes internes qui devraient pouvoir modifier la liste et des méthodes publiques qui ne devraient pas permettre la modification, je vous suggère de le faire.

// 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;
}

(Vos objets Bean semblent déjà immuables.)


Remarque: si vous utilisez Java 8+, votre getMutableList peut être exprimé comme suit:

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

Utilisez Collections.unmodifiableList() . Vous transmettez votre ArrayList d'origine et elle renvoie une liste qui lève une exception si vous essayez d'ajouter, de supprimer ou de déplacer des éléments. Par exemple, utilisez return Collections.unmodifiableList(beanList); au lieu de return beanList; à la fin de getImmutableList(). main() lève une exception. La classe Collections possède également des méthodes pour tous les autres types de collection courants, en plus de list.

7
Mad Physicist

Dans le JDK 8:

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

Dans le JDK 9:

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

référence

3
Roushan

La solution ci-dessous est destinée à rendre la liste immuable sans utiliser d’API. 

Objet immuable avec la variable membre ArrayList

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());
    }
}

Ainsi, la liste actuelle ne changera pas, la sortie sera toujours [A, B]

2

À partir de Java 10,List.copyOf(Collection)peut être utilisé pour renvoyer une liste non modifiable de la collection donnée. A partir du code source de la méthode List.copyOf:

  • si la collection donnée est une liste non modifiable, List.copyOf() ne créera pas de copie.

  • si la collection donnée est modifiable et modifiée, la liste renvoyée ne reflétera pas de telles modifications. Ce qui signifie qu'ils sont dépendants.

2
tonyhoan

Si vous êtes prêt à utiliser une bibliothèque tierce, Eclipse Collection s vous permet de convertir de MutableList à ImmutableList et vice-versa.

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

Cela fonctionne aussi avec les collections primitives.

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

Si vous avez une ArrayList en tant que mutable List, ce qui suit fonctionnera.

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

Remarque: je suis un partisan des collections Eclipse.

1
Donald Raab