Classe immuable avec liste
Before Update List ABC 101 [java, spring, hibernate, rest] After Update List ABC 101 [java, spring, hibernate, rest, Hibernate]
Test d'une classe immuable pour interrompre l'immuabilité
package com.text.immutable;
import java.util.ArrayList;
import java.util.List;
class ImmutablityTest
{
public static void main(String args[])
{
List<String> courses = new ArrayList<String>();
courses.add("java");
courses.add("spring");
courses.add("hibernate");
courses.add("rest");
Student s = new Student("ABC", 101, courses);
System.out.println("Before Update List");
System.out.println(s.getName());
System.out.println(s.getRegNo());
System.out.println(s.getCourses());
courses.add("Hibernate"); // Able to Change which affect final OutCome
//s.getCourses().add("SpringBoot"); // giving Exception in thread "main" java.lang.UnsupportedOperationException
System.out.println("After Update List");
System.out.println(s.getName());
System.out.println(s.getRegNo());
System.out.println(s.getCourses());
}
}
La sortie est
package com.text.immutable;
import java.util.Collections;
import java.util.List;
// An immutable class Student
public final class Student
{
final String name;
final int regNo;
final List<String> courses; // want to make Immutable
public Student(String name, int regNo, List<String> courses)
{
this.name = name;
this.regNo = regNo;
this.courses = Collections.unmodifiableList(courses);
}
public String getName()
{
return name;
}
public int getRegNo()
{
return regNo;
}
public List<String> getCourses() {
return courses;
}
}
4 Réponses :
Lisez about immutableLists et vous constaterez qu'un immuable et un non modifiable ne sont pas les mêmes .
Je suppose (d'après votre question) que vous attendez une liste non modifiable que vous ne créez tout simplement pas ...
voir cette réponse pour une solution appropriée
this.courses = Collections.unmodifiableList (cours);
Cela crée, comme son nom l'indique, une liste non modifiable . Mais ce n'est qu'une vue de la liste d'origine . Ainsi, les modifications apportées à cette liste originale deviennent visibles dans votre vue "non modifiable".
En cas de doute: clonez votre liste, comme:
return Collections.unmodifiableList(courses);Et puis assurez-vous que votre getter fait: p >
this.courses = new ArrayList<>(courses);
oui - il doit être non modifiable - pas immuable ^ _ ^ +1
this.courses = Collections.unmodifiableList (new ArrayList <> (courses)); devrait également suffire
Merci @GhostCat, le vôtre fonctionne également mais Koziolek travaille également sur la solution la meilleure et la plus appropriée
Avec Collections.unmodifiableList , il crée un wrapper autour de la liste d'origine et cet objet wrapper n'est pas modifiable. La liste d'origine peut encore être mise à jour.
Ainsi, pour que la liste List soit immuable, vous pouvez utiliser la bibliothèque commune de la collection Apache.
Liste
ImmutableList a remplacé la méthode List.add pour toujours lancer l'exception java.lang.UnsupportedOperationException
La deuxième alternative est de créer la liste à l'intérieur du constructeur lui-même.
Student s = new Student("ABC", 101, "a","a","a","a");
Et appelez-le comme ceci:
public Student(String name, int regNo, String... args)
{
this.name = name;
this.regNo = regNo;
courses = (List)Arrays.asList(args);
}
Pas le meilleur dans le contexte de la mémoire, mais fonctionne:
// An immutable class Student
public final class Student
{
final String name;
final int regNo;
final List<String> courses; // want to make Immutable
public Student(String name, int regNo, List<String> courses)
{
this.name = name;
this.regNo = regNo;
this.courses = new ArrayList(courses);
}
public String getName()
{
return name;
}
public int getRegNo()
{
return regNo;
}
public List<String> getCourses() {
return new ArrayList(courses);
}
}
En entrée (dans le constructeur) vous créez une copie de liste et en sortie (en getter) vous créez une copie.
Merci @Koziolek, le vôtre fonctionne également, mais GhostCat fonctionne également, lequel est la meilleure et la solution appropriée
Clonez la liste lors de sa définition.
je les mélange toujours - votre question est donc très raisonnable +1