A lista em Java pode conter elementos repetidos (código hash e iguais), portanto, há duas maneiras de desduplicar a lista:
Opção 1: Pode ser implementado através do HashSet. O código é o seguinte:
Copie o código do código da seguinte forma:
classe Aluno {
id de string privado;
nome da string privada;
aluno público(String id, String nome) {
super();
isto.id = id;
este.nome = nome;
}
@Substituir
string pública paraString() {
return "Aluno [id=" + id + ", nome=" + nome + "]";
}
@Substituir
public int hashCode() {
final int primo = 31;
resultado interno = 1;
resultado = primo * resultado + ((id == nulo) ? 0: id.hashCode());
resultado = primo * resultado + ((nome == nulo) ? 0 : nome.hashCode());
resultado de retorno;
}
@Substituir
público booleano igual a(Objeto obj) {
if (este == obj) {
retornar verdadeiro;
}
if (obj == nulo) {
retornar falso;
}
if (getClass()! = obj.getClass()) {
retornar falso;
}
Aluno outro = (Aluno) obj;
if (id == nulo) {
if (outro.id! = nulo) {
retornar falso;
}
} else if (!id.equals(outro.id)) {
retornar falso;
}
if (nome == nulo) {
if (outro.nome! = nulo) {
retornar falso;
}
} else if (!nome.equals(outro.nome)) {
retornar falso;
}
retornar verdadeiro;
}
}
Dois métodos, hashCode e equals, devem ser implementados. Veremos em breve porque os códigos de operação específicos devem ser implementados da seguinte forma:
Copie o código do código da seguinte forma:
private static void removeListDuplicateObject() {
List<Aluno> lista = new ArrayList<Aluno>();
for (int i = 0; i < 10; i++) {
Aluno aluno = novo Aluno("id", "nome");
lista.add(aluno);
}
System.out.println(Arrays.toString(list.toArray()));
Set<Aluno> set = new HashSet<Aluno>();
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 chamada:
Copie o código do código da seguinte forma:
public static void main(String[] args) {
removeListDuplicateObject();
}
Ao usar HashSet para realizar operações de desduplicação, por que precisamos substituir os métodos hashCode e equals?
Vamos verificar o código-fonte da operação add do HashSet da seguinte forma:
Copie o código do código da seguinte forma:
adição booleana pública (E e) {
retornar mapa.put(e, PRESENTE)==nulo;
}
HashMap é chamado para operação. Vejamos a operação put do HashMap:
Copie o código do código da seguinte forma:
public V put(chave K, valor V) {
if (chave == nulo)
retornar putForNullKey(valor);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = tabela[i]; e != nulo; e = e.próximo) {
Objeto k;
if (e.hash == hash && ((k = e.key) == chave || key.equals(k))) {
V valor antigo = e.valor;
e.valor = valor;
e.recordAccess(este);
retornar valorantigo;
}
}
modCont++;
addEntry(hash, chave, valor, i);
retornar nulo;
}
As coisas a serem observadas são:
Copie o código do código da seguinte forma:
if (e.hash == hash && ((k = e.key) == chave || key.equals(k))) {
...
}
Em outras palavras, os códigos hash são iguais e iguais (==).
Complexidade: basta atravessar de um lado, O(n)
Opção 2: Percorra diretamente a Lista e implemente as operações contém e adicione. O código é o seguinte:
Copie o código do código da seguinte forma:
private static void removeListDuplicateObjectByList() {
List<Aluno> lista = new ArrayList<Aluno>();
for (int i = 0; i < 10; i++) {
Aluno aluno = novo Aluno("id", "nome");
lista.add(aluno);
}
System.out.println(Arrays.toString(list.toArray()));
List<Aluno> listUniq = new ArrayList<Aluno>();
for (Aluno aluno: lista) {
if (!listUniq.contains(aluno)) {
listaUniq.add(aluno);
}
}
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()));
}
Outros são iguais aos anteriores.
Complexidade:
Durante a travessia, o método contains é chamado ao mesmo tempo. Visualizamos o código-fonte da seguinte maneira:
Copie o código do código da seguinte forma:
público booleano contém (Objeto o) {
retornar índiceOf(o) >= 0;
}
public int indexOf(Objeto o) {
if (o == nulo) {
for (int i = 0; i <tamanho; i++)
if (elementoDados[i]==nulo)
retornar eu;
} outro {
for (int i = 0; i <tamanho; i++)
if (o.equals(elementData[i]))
retornar eu;
}
retornar -1;
}
Você pode ver que outra operação de passagem foi executada na nova lista. Ou seja, 1+2+....+n, a complexidade é O(n*n)
para concluir:
A solução 1 é altamente eficiente, ou seja, utiliza HashSet para realizar operações de desduplicação.