example - sort arraylist object java




¿Qué hace Collections.unmodifiableSet() en Java? (4)

El Collections.unmodifiableSet(Set<? extends T>) creará un contenedor en el set original. Este conjunto de envoltorio no puede ser modificado. pero aún así el conjunto original puede ser modificado.

Ejemplo:

 Set<String> actualSet=new HashSet<String>(); //Creating set

Añadiendo algunos elementos.

actualSet.add("aaa");
actualSet.add("bbb");

Imprimiendo elementos añadidos

System.out.println(actualSet);   //[aaa, bbb]

Coloque el actualSet en un conjunto no modificable y asignado a una nueva referencia ( wrapperSet ).

Set<String> wrapperSet=Collections.unmodifiableSet(orginalSet);

Imprimir el wrapperSet. por lo que tendrá valores actualSet

System.out.println(wrapperSet);   //[aaa, bbb]

intentemos eliminar / agregar un elemento en wrapperSet .

wrapperSet.remove("aaa");   //UnSupportedOperationException 

Añadir un elemento más en actualSet

    actualSet .add("ccc");

Imprimir actualSet y wrapperSet . Ambos valores de conjunto son iguales. así que si agrega / elimina elementos en el conjunto real, los cambios también se reflejarán en el conjunto de envoltura.

    System.out.println(actualSet);  //[aaa, ccc, bbb]
    System.out.println(wrapperSet);  // [aaa, ccc, bbb]

Uso:

Este Collections.unmodifiableSet(Set<? extends T>) se usa para evitar la modificación del método getter de Set de cualquier objeto. Digamos

public class Department{

    private Set<User> users=new HashSet<User>();

    public Set<User> getUsers(){
        return Collections.unmodifiableSet(users); 
    }
}

Puedo ver que Collections.unmodifiableSet devuelve una vista no modificable del conjunto dado, pero no entiendo por qué no podemos usar el modificador final para lograr esto.

En mi entendimiento, final declara una constante: algo que no puede ser modificado. Por lo tanto, si un conjunto se declara como una constante, entonces no se puede modificar: no se puede eliminar nada del conjunto y no se puede agregar nada.

¿Por qué necesitamos Collections.unmodifiableSet ?


Resuma que podemos hacer y no podemos:

Preparación:

private Set<String> words = new HashSet<>(Arrays.asList("existing word"));

Final por referencia

private final Set<String> words = new HashSet<>();

puede :

words.add("new word");

no puedo

words = new HashSet<>(); //compilation error

Final por referencia y no modificable por colección.

Set final privado de palabras = Colecciones.unmodifiableSet (palabras);

puede :

String word = words.iterator().next();

no puedo

words = new HashSet<>(); // compilation error
words.add("new word"); // runtime error UnsupportedOperationException

Final por referencia y no modificable por colección pero mutuo como objeto de colección.

Pero si tiene la colección con objetos mutual , puede CAMBIAR el estado interno de ese objeto.

 class A {
       public int a; //mutable field. I can change it after initialization
       public A(int a) {this.a = a;}
     }

 private final Set<A> set = Collections.unmodifiableSet(Arrays.asList(new A(25)));

Todavia no puedo

set = new HashSet<>(); // compilation error
set.add(new A(777)); // runtime error UnsupportedOperationException

Pero puede

 A custom = words.iterator().next(); //here custom.a = 25;
 custom.a = 777; //here first element of **final, unmodifible** collection 
    //was changed from 25 to 777

final no es (estilo C ++) const . A diferencia de C ++, Java no tiene métodos const ni nada de eso, y los métodos que pueden cambiar el objeto se pueden llamar a través de una referencia final .

Collections.unmodifiable* es un contenedor que impone (solo en tiempo de ejecución, no en tiempo de compilación) la capacidad de solo lectura de la colección en cuestión.


final solo garantiza que la referencia al objeto que representa la variable no se puede cambiar, no hace nada por la instancia del objeto y su mutabilidad.

final Set s = new Set(); solo garantiza que no puedes hacer s = new Set(); de nuevo. No hace que el conjunto no sea modificable, si no pudieras agregarle nada para empezar. Entonces, para que quede realmente claro, la final solo afecta a la referencia de variable, no al objeto al que apunta la referencia.

Puedo hacer lo siguiente:

final List<String> l = new ArrayList<String>();
l.add("hello");
l.add("world");
l.remove(0);

pero no puedo hacer esto

l = new ArrayList<String>();

otra vez debido a la final no puedo modificar a qué apunta la variable l.

Tiene que hacer una de las siguientes tres cosas para hacer que un subproceso de contenedor de la colección sea seguro.

java.util.Collections.syncronizedXXX();

o

java.util.Collections.unmodifiableXXX();

o use uno de los contenedores apropiados del java.util.concurrency.* package .

si tuviera un objeto Person y lo hiciera final Person p = new Person("me"); significa que no puedo reasignar p para apuntar a otro objeto Person . Todavía puedo hacer p.setFirstName("you");

Lo que confunde la situación es que

final int PI = 3.14;
final String greeting = "Hello World!";

Parecen const en C ++, cuando en realidad los objetos a los que apuntan son inmutables / no modificables por naturaleza. Los contenedores u objetos con métodos de mutación que pueden alterar el estado interno del objeto no son const solo que la referencia a esos objetos es final y no se puede reasignar para hacer referencia a otro objeto.





unmodifiable