Como descobrir dados duplicados em um ArrayList

Bom dia amigos,

Estou com um probleminha e gostaria de conhecer algumas possíveis soluções. É o seguinte, tenho uma funcionalidade de upload de planilha, com uma aba e uma coluna, num sistema e populo um ArrayList sem problemas. A minha dúvida é:

1 - Com o List populado, faço as devidas verificações e depois populo um outro List, com os dados validados, e mando esse List para um método persistir no BD. O List é populado com nomes de cidades e podem existir cidades repetidas, como consigo saber quais são os dados repetidos? lembrando que estou usando o Java 1.4.

Vlw!

Abs…

Será que o uso de um Tree Set resolve seu problema (insira as cidades em um Set ao invés de inserir em outro List)? Você quer saber as cidades repetidas ou não quer que elas sejam inseridas no outro List?
Obs. Os sets não permitem inclusão de objetos equivalentes.
Obs2. Se cidade for um tipo de dado (classe) implementar equals e hashCode.

Lembre-se apenas que o TreeSet ordena os dados.

Se não for necessário ordenação, é melhor utilizar um HashSet.

Mas o HashSet também não é.

E o HashSet altera a ordem dos dados. Use-o somente se a ordenação não importar.
Se for necessário manter a ordenação, use um LinkedHashSet.

Se for interessante nomes de cidades ordenados, e esses nomes tiverem acentos, talvez seja uma boa idéia associar seu TreeSet a um Collator. Assim você obtém uma ordem alfabética mais natural.

[quote=ViniGodoy]
Se for interessante nomes de cidades ordenados, e esses nomes tiverem acentos, talvez seja uma boa idéia associar seu TreeSet a um Collator. Assim você obtém uma ordem alfabética mais natural.[/quote]

Um exemplo: http://www.guj.com.br/posts/list/48001.java#250910

Amigos vlw pelas respostas, mas tentei implementar o HashSet no Java 1.4 e não funcionou, ele não tirou as cidades duplicadas:

HashSet set = new HashSet(lCitiesPlan);
Iterator it = set.iterator();
while (it.hasNext() ){
	System.out.println("City Não Duplicada: " + it.next());				
}

O que está errado? Só deveria aparecer as cidades não duplicadas… certo?

Vlw!!

Por que você está usando Java 1.4? :shock:

Em todo caso, o que é lCitiesPlan? Se for uma lista de objetos da classe City, certifique-se que os métodos equals e hashCode estejam implementados corretamente.
Se for usar um TreeSet, certifique-se que a classe que está dentro da lista implementa Comparable.

A classe String atende a ambas as exigências.

Amigo ViniGodoy,

Sim, lCitiesPlan é um List da classe de objetos City.
Não implementei os métodos equals e hashCode. Como poderia implementa-los?

Vlw!

Se estiver utilizando o Eclipse, peça pra ele gerar.

Clique com botão direito dentro da classe, source, Generate equals and hashcode.

Blz, já gerei… Usei os atributos Id e Descricao da classe CityVo, conforme abaixo… Agora como faço para descobrir a duplicidade no HashSet?

public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((descricao == null) ? 0 : descricao.hashCode());
		result = prime * result + id;
		return result;
	}
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		CityVo other = (CityVo) obj;
		if (descricao == null) {
			if (other.descricao != null)
				return false;
		} else if (!descricao.equals(other.descricao))
			return false;
		if (id != other.id)
			return false;
		return true;
	}

Vlw!

Abs…

Aproveitando o tópico, alguém poderia sugerir material(free na net) sobre estruturas de dados em java, que além de mostrar as diferenças, também exemplifique em qual situação usar cada uma delas?

E o HashSet altera a ordem dos dados. Use-o somente se a ordenação não importar.
Se for necessário manter a ordenação, use um LinkedHashSet.

Se for interessante nomes de cidades ordenados, e esses nomes tiverem acentos, talvez seja uma boa idéia associar seu TreeSet a um Collator. Assim você obtém uma ordem alfabética mais natural.[/quote]

Você precisa ordenar as cidades? Se precisar, é melhor usar um TreeSet e só implementar Comparable. Em todo caso, é bom entender certinho como funciona o equals e hashCode, pois nem sempre a implementação do eclipse e do Netbeans é a mais adequada.

Dê uma lida no javadoc dos métodos e nos itens 7 e 8 desse material:
http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf

http://download.oracle.com/javase/tutorial/collections/index.html
http://java.sun.com/developer/Books/javaprogramming/corejava/

Com o equals e o hashCode implementados, seu HashSet vai funcionar como vc esperava. Tente repetir o algoritmo de testes que vc já postou aqui, e você vai ver que o resultado agora contém apenas cidades sem duplicação.

[quote=ViniGodoy]Você precisa ordenar as cidades? Se precisar, é melhor usar um TreeSet e só implementar Comparable. Em todo caso, é bom entender certinho como funciona o equals e hashCode, pois nem sempre a implementação do eclipse e do Netbeans é a mais adequada.
[/quote]

Estou pensando e não sei um caso onde a implementação do eclipse e netbeans não atenda.
Qual caso seria esse? Tem como passar um link ou algo pra eu dar uma estudada?

Valeu.

Não serve os dois links que eu já passei?

O caso seria quando seu conceito de igualdade engloba menos atributos que os que a classe tem. Por exemplo, você poderia definir que dois objetos são iguais se seus IDs forem iguais, e nada mais.

Mas quando vc vai gerar o equals e o hashcode pelo eclipse, ele pergunta pra vc qual o atributo que vc quer que ele se baseie para comparar. Não faria sentido usar sempre todos os atributos no equals e hashcode.

É isso que vc quis dizer?

Depende de como você faz equals com atributos como listas e outros objetos.
Algumas vezes a implementação do hashCode dele também é rebuscada demais. Por exemplo, se seu conceito de igualdade é o id, o próprio id é um bom hashCode.

Bem, não custa entender o que o método faz, não acha?