Extendendo a classe ArrayList para criar listas sem repetição
Dica publicada em Java / Miscelânea
Extendendo a classe ArrayList para criar listas sem repetição
Olá, amigos do VOL.
Hoje, deixo uma dica sobre como criar, rapidamente, listas de vetores/arrays sem repetição, em Java.
Estou deixando essa dica, porque depois de "googlar" por horas e horas, não achei um código decente que fizesse o acima.
O que mais se acha na Net, são usuários avançados sugerindo implementar comparable e iterator. Mas isso gera um código grande e complexo, e nem sempre atende a todas às necessidades.
Eu até vi alguns usuários bravos no Stack Overflow dizendo que em C++, a classe std::Set provê isso com facilidade, e que Java só faz a gente passar raiva. Mas, eu acho que não é bem por aí. Java também te dá isso, mas por um caminho mais longo, só isso.
A solução que acabei chegando depois de muita dor, tentativa e erro, foi estender a classe ArrayList e sobrecarregar o método contains(), e é isso que vou explicar como fazer.
Primeiro, crie uma classe que estende a classe ArrayList, como abaixo:
Para testar se a classe está funcionando, crie uma classe principal e chame-a, tente adicionar registros repetidos e teste o conteúdo das listas de arrays depois, assim:
A saída no console, será:
Foram inseridos apenas 2 arrays na lista. :)
Um abraço a todos.
Espero que ajude.
Hoje, deixo uma dica sobre como criar, rapidamente, listas de vetores/arrays sem repetição, em Java.
Estou deixando essa dica, porque depois de "googlar" por horas e horas, não achei um código decente que fizesse o acima.
O que mais se acha na Net, são usuários avançados sugerindo implementar comparable e iterator. Mas isso gera um código grande e complexo, e nem sempre atende a todas às necessidades.
Eu até vi alguns usuários bravos no Stack Overflow dizendo que em C++, a classe std::Set provê isso com facilidade, e que Java só faz a gente passar raiva. Mas, eu acho que não é bem por aí. Java também te dá isso, mas por um caminho mais longo, só isso.
A solução que acabei chegando depois de muita dor, tentativa e erro, foi estender a classe ArrayList e sobrecarregar o método contains(), e é isso que vou explicar como fazer.
Primeiro, crie uma classe que estende a classe ArrayList, como abaixo:
import java.util.ArrayList;
import java.util.Arrays;
public class Lista<T> extends ArrayList<T>{
public Lista() {
super(); //chame o construtor de ArrayList
}
/*Esse método sobrecarrega o metodo contains, e irá funcionar
com arrays de objetos. Você pode sobregarregar, sobrescrever
ou adicionar mais métodos a esta classe, de forma que
ela fique ainda mais poderosa, e usar ela, em vez de ArrayList.
*/
public boolean contains(Object[] o){
//percorre o bjeto 'Lista':
for(int i=0; i< this.size(); i++){
/* cria um array de objetos e faz um 'type-cast'
desta própria classe atribuindo a ele o valor do
elemento, e isso para cada elemento, de forma que
todos os elementos sejam tratados como arrays de
objetos:
*/
Object[] toCompare = (Object[])this.get(i);
/* através do metodo equals da classe Arrays, e do loop
for-each, verifica se algum elemento do array candidato ao
add() já está adicionado na lista, se sim é retornado true,
se não, é retornado false.
*/
if(Arrays.equals(o, toCompare)){
return true;
}
}
return false;
}
}
import java.util.Arrays;
public class Lista<T> extends ArrayList<T>{
public Lista() {
super(); //chame o construtor de ArrayList
}
/*Esse método sobrecarrega o metodo contains, e irá funcionar
com arrays de objetos. Você pode sobregarregar, sobrescrever
ou adicionar mais métodos a esta classe, de forma que
ela fique ainda mais poderosa, e usar ela, em vez de ArrayList.
*/
public boolean contains(Object[] o){
//percorre o bjeto 'Lista':
for(int i=0; i< this.size(); i++){
/* cria um array de objetos e faz um 'type-cast'
desta própria classe atribuindo a ele o valor do
elemento, e isso para cada elemento, de forma que
todos os elementos sejam tratados como arrays de
objetos:
*/
Object[] toCompare = (Object[])this.get(i);
/* através do metodo equals da classe Arrays, e do loop
for-each, verifica se algum elemento do array candidato ao
add() já está adicionado na lista, se sim é retornado true,
se não, é retornado false.
*/
if(Arrays.equals(o, toCompare)){
return true;
}
}
return false;
}
}
Para testar se a classe está funcionando, crie uma classe principal e chame-a, tente adicionar registros repetidos e teste o conteúdo das listas de arrays depois, assim:
public static void main(String[] args) {
Lista<Object[]> lista = new Lista<Object[]>(); //Instancia a classe que criamos
for(int i=0; i<100; i++){ //tenta inserir 100x a mesma coisa
if(!lista.contains(new Object[]{ "bbb", true, 132.0, 1234 })) //Observe que existem vários tipos de dados nesse array
lista.add(new Object[]{ "bbb", true, 132.0, 1234 });
if(!lista.contains(new Object[]{ "aaa", false, 132.0, 1234 }))
lista.add(new Object[]{ "aaa", false, 132.0, 1234 });
}
for(int j=0; j<lista.size(); j++){
for(int c=0; c<lista.get(j).length; c++){
System.out.print(lista.get(j)[c]+"-");
}
System.out.print("\n");
}
}
Lista<Object[]> lista = new Lista<Object[]>(); //Instancia a classe que criamos
for(int i=0; i<100; i++){ //tenta inserir 100x a mesma coisa
if(!lista.contains(new Object[]{ "bbb", true, 132.0, 1234 })) //Observe que existem vários tipos de dados nesse array
lista.add(new Object[]{ "bbb", true, 132.0, 1234 });
if(!lista.contains(new Object[]{ "aaa", false, 132.0, 1234 }))
lista.add(new Object[]{ "aaa", false, 132.0, 1234 });
}
for(int j=0; j<lista.size(); j++){
for(int c=0; c<lista.get(j).length; c++){
System.out.print(lista.get(j)[c]+"-");
}
System.out.print("\n");
}
}
A saída no console, será:
bbb-true-132.0-1234-
aaa-false-132.0-1234-
Foram inseridos apenas 2 arrays na lista. :)
Um abraço a todos.
Espero que ajude.
Acho que você está começando a programar em Java, a sua solução não é a mais recomendada. Porque?
O Java já possui um conjunto de classes que não permitem elementos duplicados. Essas classes implementam a interface Set, você pode conferir mais informações na documentação aqui -> http://docs.oracle.com/javase/7/docs/api/index.html?java/util/Set.html.
Nesse link (http://javafree.uol.com.br/artigo/847654/) em português do JavaFree tem uma excelente explicação sobre as classes da API padrão que trabalham com coleções.
Espero ter ajudado