[Resolvido]TreeSet com Comparable e Comparator

3 respostas
Rafael_Mesquita_Mour

Pessoal bom dia, estou estudando um pouco mais sobre classificação de conjuntos utilizando as interfaces Comparable e Comparator e me deparei com uma dúvida que está me deixando maluco. É o seguinte, eu criei uma classe Pizza que possui duas variáveis de instância, que são: String sabor, Double preco. Essa classe já implementa a interface Comparable e utiliza como critério de classificação do método compareTo(Object o) a variável “sabor”. Como vocês poderão observar já sobrepus os métodos equals(Object o) e hashCode(), para que não haja duplicidade no meu conjunto TreeSet. Segue abaixo o código da classe Pizza:

import java.util.Comparator;

public class Pizza implements Comparable{
	String sabor;
	Double preco;

	public Pizza(String sabor, Double preco) {
		this.sabor = sabor;
		this.preco = preco;
	}
	
	public boolean equals(Object o){
		if((o instanceof Pizza) && ((Pizza)o).sabor.equals(this.sabor)){
			return true;
		} else {
			return false;
		}
	}
	
	public int hashCode(){
		return sabor.length();
	}
	
	public int compareTo(Object o){
		return this.sabor.compareTo(((Pizza)o).sabor);
	}	
	
	public String toString(){
		return sabor + " " + preco + "";
	}
}

Criei também uma classe ComparatorPrecoPizza que implementa a interface Comparator, e utiliza como critério de classificação a variável preco. Segue abaixo o código da classe ComparatorPrecoPizza:

import java.util.Comparator;

public class ComparatorPrecoPizza implements Comparator{
	public int compare(Object o1, Object o2){
		return ((Pizza)o1).preco.compareTo(((Pizza)o2).preco);
	}
}

Agora, vou mostrar o código da classe de teste que eu criei para testar a classificação utilizando ambas as interfaces:

import java.util.Set;
import java.util.TreeSet;

public class ArrayListPizzaTest {
	public static void main(String[] args) {
		Pizza p1 = new Pizza("Mussarela", 12.9);
		Pizza p2 = new Pizza("Calabreza", 10.9);
		Pizza p3 = new Pizza("Baiana", 15.9);
		Pizza p4 = new Pizza("Quatro Queijos", 18.2);
		Pizza p5 = new Pizza("Portuguesa", 19.9);
		Pizza p6 = new Pizza("Americana", 15.0);
		Pizza p7 = new Pizza("Quatro Queijos", 10.2);
		
		Set cardapio = new TreeSet();
		//Set cardapio = new TreeSet(new ComparatorPrecoPizza());
		
		cardapio.add(p1);
		cardapio.add(p2);
		cardapio.add(p3);
		cardapio.add(p4);
		cardapio.add(p5);
		cardapio.add(p6);
		cardapio.add(p7);
		
//		System.out.println(p1.hashCode());
//		System.out.println(p4.hashCode());
//		System.out.println(p7.hashCode());
		
		System.out.println(cardapio);
	}
}

A minha dúvida é a seguinte: Por que quando eu descomento a linha 15 e comento a linha 14, a minha saída exibe duplicidade na pizza Quatro Queijos? Se eu comentar a linha 15 e deixar a linha 14 descomentada, a minha saída é a correta, pelo menos é a saída que eu espero obter, porém se comento a linha 14 e descomento a linha 15 o problema aparece para me atormentar.

Vou mostrar aqui ambas as saídas para que vocês possam me ajudar:

Saída com a linha 14 descomentada e a linha 15 comentada:

//Essa é a saída que eu espero, que eu gostaria que se repetisse ao descomentar a linha 15
[Americana 15.0, Baiana 15.9, Calabreza 10.9, Mussarela 12.9, Portuguesa 19.9, Quatro Queijos 18.2]

Saída com a linha 14 comentada e a linha 15 descomentada:

//Essa é a saída que está exibindo duplicidade, percebam a pizza "Quatro Queijos"
[Quatro Queijos 10.2, Calabreza 10.9, Mussarela 12.9, Americana 15.0, Baiana 15.9, Quatro Queijos 18.2, Portuguesa 19.9]

Alguém poderia me dar uma luz nessa dúvida? Se eu me expressei mal em algum momento me avisem que eu tento explicar melhor.

Obrigado!

Rafael Mesquita

3 Respostas

E

TreeSet não usa nem hashCode nem equals. Ele só usa o compareTo. Se há duas pizzas com preços diferentes, e como você disse que pizzas de preços diferentes estão em ordem crescente, então ele irá cadastrar a pizza com preço 10.2 e a pizza com preço 18.2.

Outra coisa: se houver 2 pizzas com o mesmo preço, ele vai cadastrar apenas a primeira delas, não a segunda. OK?

Rafael_Mesquita_Mour

Consegui resolver aqui. O meu problema não estava no método compareTo(Object o), e sim na classe ComparatorPrecoPizza que implementa Comparator. O que estava acontecendo é que, dentro do método compare(Object o1, Object o2) eu estava comparando o preço das pizzas do conjunto, então se não encontrasse preços iguais ele passava numa boa. Só que a minha ideia é não permitir Pizzas iguais a partir do nome, então apenas alterei o método compare(Object o1, Object o2) para:

public class ComparatorPrecoPizza implements Comparator{
	public int compare(Object o1, Object o2){
		Pizza p1 = (Pizza)o1;
		Pizza p2 = (Pizza)o2;
		
		return (int)(p1.preco - p2.preco);		
	}
}

Obrigado! O tópico já pode ser fechado.

E

Não considero que isso esteja resolvido. A única coisa que você fez foi fazer seu teste dar o resultado que você queria. Mas você realmente não entendeu o espírito da coisa.

Criado 10 de novembro de 2011
Ultima resposta 10 de nov. de 2011
Respostas 3
Participantes 2