La lista en Java puede contener elementos repetidos (código hash e iguales), por lo que hay dos formas de deduplicar la lista:
Opción 1: se puede implementar a través de HashSet. El código es el siguiente:
Copie el código de código de la siguiente manera:
clase estudiante {
identificación de cadena privada;
nombre de cadena privada;
Estudiante público (ID de cadena, nombre de cadena) {
súper();
this.id = identificación;
this.nombre = nombre;
}
@Anular
cadena pública toString() {
return "Estudiante [id=" + id + ", nombre=" + nombre + "]";
}
@Anular
público int código hash() {
final int primo = 31;
resultado entero = 1;
resultado = principal * resultado + ((id == null)? 0: id.hashCode());
resultado = primo * resultado + ((nombre == nulo)? 0: nombre.hashCode());
resultado de devolución;
}
@Anular
público booleano es igual (Objeto obj) {
si (esto == obj) {
devolver verdadero;
}
si (obj == nulo) {
devolver falso;
}
si (getClass()! = obj.getClass()) {
devolver falso;
}
Otro estudiante = (Estudiante) obj;
si (id == nulo) {
si (otro.id! = nulo) {
devolver falso;
}
} else if (!id.equals(otro.id)) {
devolver falso;
}
si (nombre == nulo) {
if (otro.nombre!= nulo) {
devolver falso;
}
} else if (!nombre.equals(otro.nombre)) {
devolver falso;
}
devolver verdadero;
}
}
Se deben implementar dos métodos, hashCode y equals. Veremos en un momento por qué los códigos de operación específicos deben implementarse de la siguiente manera:
Copie el código de código de la siguiente manera:
vacío estático privado removeListDuplicateObject() {
Lista<Estudiante> lista = new ArrayList<Estudiante>();
para (int i = 0; i < 10; i++) {
Estudiante estudiante = nuevo Estudiante("id", "nombre");
lista.add(estudiante);
}
System.out.println(Arrays.toString(list.toArray()));
Set<Estudiante> set = new HashSet<Estudiante>();
set.addAll(lista);
System.out.println(Arrays.toString(set.toArray()));
lista.removeAll(lista);
set.removeAll(conjunto);
System.out.println(Arrays.toString(list.toArray()));
System.out.println(Arrays.toString(set.toArray()));
}
Código de llamada:
Copie el código de código de la siguiente manera:
público estático vacío principal (String [] argumentos) {
eliminarListDuplicateObject();
}
Cuando utilizamos HashSet para realizar operaciones de deduplicación, ¿por qué necesitamos anular los métodos hashCode y equals?
Verifiquemos el código fuente de la operación de adición de HashSet de la siguiente manera:
Copie el código de código de la siguiente manera:
agregar booleano público (E e) {
return map.put(e, PRESENTE)==null;
}
Se llama a HashMap para su operación. Veamos la operación de colocación de HashMap:
Copie el código de código de la siguiente manera:
public V put (clave K, valor V) {
si (clave == nula)
devolver putForNullKey(valor);
int hash = hash(key.hashCode());
int i = indexFor(hash, tabla.longitud);
for (Entrada<K,V> e = tabla[i]; e != nulo; e = e.next) {
Objeto k;
if (e.hash == hash && ((k = e.key) == clave || key.equals(k))) {
V oldValue = e.valor;
e.valor = valor;
e.recordAccess(esto);
devolver valor antiguo;
}
}
modCount++;
addEntry(hash, clave, valor, i);
devolver nulo;
}
Las cosas a tener en cuenta son:
Copie el código de código de la siguiente manera:
if (e.hash == hash && ((k = e.key) == clave || key.equals(k))) {
...
}
En otras palabras, los códigos hash son iguales e iguales (==).
Complejidad: simplemente recorra por un lado, O (n)
Opción 2: recorrer directamente la Lista e implementar las operaciones de contenido y adición. El código es el siguiente:
Copie el código de código de la siguiente manera:
vacío estático privado removeListDuplicateObjectByList() {
Lista<Estudiante> lista = new ArrayList<Estudiante>();
para (int i = 0; i < 10; i++) {
Estudiante estudiante = nuevo Estudiante("id", "nombre");
lista.add(estudiante);
}
System.out.println(Arrays.toString(list.toArray()));
Lista<Estudiante> listUniq = new ArrayList<Estudiante>();
para (Estudiante estudiante: lista) {
if (!listUniq.contiene(estudiante)) {
listUniq.add(estudiante);
}
}
System.out.println(Arrays.toString(listUniq.toArray()));
lista.removeAll(lista);
listaUniq.removeAll(listaUniq);
System.out.println(Arrays.toString(list.toArray()));
System.out.println(Arrays.toString(listUniq.toArray()));
}
Otros son iguales que los anteriores.
Complejidad:
Mientras recorre, se llama al método contiene al mismo tiempo. Vemos el código fuente de la siguiente manera:
Copie el código de código de la siguiente manera:
booleano público contiene (Objeto o) {
devolver índice de (o) >= 0;
}
public int indexOf(Objeto o) {
si (o == nulo) {
para (int i = 0; i < tamaño; i++)
si (elementoDatos[i]==nulo)
devolver yo;
} demás {
para (int i = 0; i < tamaño; i++)
si (o.equals(elementData[i]))
devolver yo;
}
devolver -1;
}
Puede ver que se ha realizado otra operación transversal en la nueva lista. Es decir, 1+2+....+n, la complejidad es O(n*n)
en conclusión:
La solución 1 es muy eficiente, es decir, utilizar HashSet para realizar operaciones de deduplicación.