[Resolvido]TreeSet com Comparable e Comparator

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

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?

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.

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.