Ordenação sem Duplicatas TreeSet

E ai galera blz !

Estou com o seguinte problema estou tentando fazer uma ordenação de sem duplicatas utilizando a
classe treeset, mas nao esta dando certo o treeset assim como hashset não utiliza os metodos hashcode e equals ?
acabei fazendo assim.

Mas não sei se é o mais adequado.

public static void main(String args[]){

	ArrayList<ClasseB> b = new ArrayList<ClasseB>();
	b.add(new ClasseB("Robson",1,"rln00@rln"));
	b.add(new ClasseB("Juka",2,"rln00@rln"));
	b.add(new ClasseB("Fernanda",3,"rln@rln"));
	b.add(new ClasseB("Aernanda",4,"rln@rln"));
	System.out.println(b);
	
	HashSet<ClasseB> c = new HashSet<ClasseB>();
	c.addAll(b);
	System.out.println(c);
	
	Set<ClasseB> order = new TreeSet<ClasseB>(c);
	System.out.println(order);
	
}

Obrigado.

De acordo com a documentação do SortedSet, a ordenação é feita em classes que implementem a interface Comparable, ou por via um Comparator passado na criação da coleção, no caso o TreeSet.

Com relação a ordenação eu já implemente a CompareTo na ClasseB mas o que não consigo fazer com o treeSet
é parte de não conter duplicatas que o hashset faz.

Poderiam dar uma força ?

Valeu.

Leia o contrato que existe entre o hashcode e o equals na API. Faça com que sua “ClasseB” siga esse contrato.

[quote=robson.nunes]Com relação a ordenação eu já implemente a CompareTo na ClasseB mas o que não consigo fazer com o treeSet
é parte de não conter duplicatas que o hashset faz.

Poderiam dar uma força ?

Valeu.[/quote]

Todos os Sets não aceitam duplicatas, inclusive o TreeSet. Para evitar duplicatas, o Set usa o método equals que você deve sobreescrever na tua classe. A ordenação só acontece em SortedSets, que usa Comparable ou Comparator, como falei.

Exemplo:

public class Pessoa implements Comparable<Pessoa> {

	private long id;
	private String nome;

	public Pessoa(long id, String nome) {
		if (nome == null || nome.isEmpty())
			throw new IllegalArgumentException("O nome deve estar preenchido.");
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (int) (id ^ (id >>> 32));
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof Pessoa))
			return false;
		Pessoa other = (Pessoa) obj;
		if (id != other.id)
			return false;
		return true;
	}

	@Override
	public int compareTo(Pessoa o) {
		return nome.compareTo(o.nome);
	}
}

Então eu já fiz essa sobre escrita do equals e hascode mas pareçe que a classe TreeSet não esta chamando esses métodos só o de CompareTo que esta ok segue o código.
Pelo que percebi no modo Debug é que com a classe HashSet ele chama automaticamente o método hashcode
quando você utiliza add ou addall, mas utilizando TreeSet isso não esta aconteçendo.

ClasseA

[code]public class ClasseA {

public static void main(String args[]){

	List<ClasseB> b = new ArrayList<ClasseB>();
	b.add(new ClasseB("Robson","aaa@"));
	b.add(new ClasseB("Juka","fff@"));
	b.add(new ClasseB("Maria","fff@"));
	
	Set<ClasseB> t = new TreeSet<ClasseB>();
	t.addAll(b);
		
	System.out.println(t);
}

}

ClasseB

public class ClasseB implements Comparable {

private String nome;
private String email;

public ClasseB(String nome, String email){
	
	this.nome = nome;
	this.email = email;
}

public String getNome() {
	return nome;
}
public void setNome(String nome) {
	this.nome = nome;
}

public String getEmail() {
	return email;
}
public void setEmail(String email) {
	this.email = email;
}

@Override
public int compareTo(ClasseB o) {
	
return	this.nome.compareTo(o.getNome());
	
}

@Override
public boolean equals(Object obj) {
	
	ClasseB b = (ClasseB) obj;
	
	return getEmail().equals(b.getEmail());
}

@Override
public int hashCode() {

	return	this.email.hashCode();
	 
}

@Override
public String toString() {

	return this.nome;
} 

}
[/code]

Está dando errado por que você não está seguindo uma outra regra de um SortedSet:

A ordem natural de um objeto, isto é, quando uma classe implementa Comparable, deve ser consistente com o equals da classe.

Em outras palavras se a.compareTo(b) == 0, então a.equals(b) == true.

No teu caso, você está usando o e-mail para fazer o equals e o hashcode, e o nome para fazer o compareTo. Você deveria usar somente nome ou somente o email em ambos os casos.

Se quiser depois ordenar por nome, crie um Comparator de ClasseB por nome, e passe como parâmetro para o TreeSet durante a sua instanciação.

E ai Bruno, blz mato o problema alterei tudo para nome ai ordenou e verificou se existia duplicatas.

Eu só tenho uma última dúvida por que eu consigo fazer ordenação e verificar duplicatas com tipos direfentes no CompareTo e no equlas utilizando o HashSet, mas não com TreeSet.

Valeu.

Só uma aula antes da explicação:

O hashcode serve para podermos usar uma técnica para separar os dados no que chamamos de buckets, ou baldes de dados. Isso serve para acelerar a pesquisa por um elemento dentro de um conjunto que use esses hashes para se orientar.

Por exemplo, temos os nomes ana, bruno, camila, danilo, eduardo e fábio. O hashcode dos nomes de A a B indicam que ficarão no balde 1, C a D no balde 2, E a F no 3. Colocamos todos esses nomes do HashSet.

Agora queremos colocar mais um fábio no conjunto. Num conjunto normal, o algorítmo verificaria cada um dos nomes um a um para ver se tem um outro fábio. Iria primeiro em ana, depois bruno, camila, até chegar no último.

Com o hashcode ele verifica que fábio está no balde 3. Ele vai direto até o balde e vê que tem somente eduardo e fábio dentro.

Como o hashcode é somente uma orientação, o equals é que faz o trabalho de verdade de comparação. Por isso que equals e hashcode tem que ser um consistente com o outro, pois se colocarem um elemento no balde errado, é capaz de não acharmos ele e o elemento será duplicado.

Voltando à pergunta, o HashSet não faz ordenações, somente evita duplicatas. Pelo que o nome dele indica, ele deve usar somente o hashcode e o equals, como disse acima, para evitar duplicatas.
Do outro lado temos o TreeSet. Este usa o compareTo para se guiar até o elemento que quer encontrar, já que que ele mantém tudo ordenado. Não precisa do hashcode nem do equals, já que ele requer que o equals seja consistente com o compareTo.

Blz valeu pelas explicações.

abs