2
votes

Comment créer une classe immuable avec l'élément List dans la classe

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


2 commentaires

Clonez la liste lors de sa définition.


je les mélange toujours - votre question est donc très raisonnable +1


4 Réponses :


1
votes

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


0 commentaires

4
votes

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

3 commentaires

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



0
votes

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 cours soit immuable, vous pouvez utiliser la bibliothèque commune de la collection Apache.

Liste immutableList = com.google.common.collect.ImmutableList.of ("Geeks", "For", "Geeks");

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

}


0 commentaires

2
votes

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.


1 commentaires

Merci @Koziolek, le vôtre fonctionne également, mais GhostCat fonctionne également, lequel est la meilleure et la solution appropriée