Duvida Com Um TreeMap

9 respostas
S

Boa tarde amigos, estou aqui mais uma vez precisando da ajuda daqueles que sabem mais que eu pra me tirar uma dúvida com um detalhe sobre o código abaixo:

class ComparatorCasa implements Comparator{
	public int compare(Object o1, Object o2){
		Casa c1 = (Casa)o1;
		Casa c2 = (Casa)o2;
		return c1.numQuartos - c2.numQuartos;
	}
}
class Casa{
	String cor;
	int numQuartos;
	
	public Casa(String cor, int numQuartos){
		this.cor = cor;
		this.numQuartos = numQuartos;
	}
	public String toString(){
		return "Cor: " + cor + " Quartos: " + numQuartos;
	}
	public boolean equals(Object o){
		if(((Casa)o).numQuartos == this.numQuartos)
			return true;
		else
			return false;
	}
	public int hashCode(){
		return numQuartos;
	}	
}
public class Programa37 {
	public static void main(String[] args) {
		Casa c1 = new Casa("Branca",2);//exibe
		Casa c2 = new Casa("Verde",1);//exibe e descarta c4
		Casa c3 = new Casa("Verde",3);//exibe
		Casa c4 = new Casa("Amarela",1);//em um primeiro momento seria exibido
		Casa c5 = new Casa("Azul",5);//exibe
		ComparatorCasa cc = new ComparatorCasa();
		TreeMap t = new TreeMap(cc);
		t.put(c1, "Antonio");
		t.put(c2, "Marta");//
		t.put(c1, "Zelia");
		//t.put(null, " T");Exceção NullPointer, chave não pode ser nula, compila.
		t.put(c3, "Cesar");
		t.put(c4, "Cleber");
		t.put(c5, null);//valor pode ser nulo, compila e executa normalmente neste caso
		System.out.print(t.keySet() + " " + t.values());
		
	}
}

A saída desse código é essa:

[Cor: Verde Quartos: 1, Cor: Branca Quartos: 2, Cor: Verde Quartos: 3, Cor: Azul Quartos: 5] [Cleber, Zelia, Cesar, null]

Entendi que tenho que sobrescrever equals() e hashCode() pra eliminar duplicidades e se quiser realizar classificação dos elementos tenho que implementar ou a interface Comparator ou Comparable, a dúvida é talvez boba, mas acho que não custa perguntar, pra definir o que vai ser exibido o programa percorre o mapa de baixo para cima e quando encontra um elemento duplicado descarta o anterior? Agradeço desde já pela ajuda. Só um detalhe, não estou usando genéricos, por isso as conversões nos métodos compare() e equals().

9 Respostas

H

Ele apaga o velho e coloca o novo. [=

E
  1. Um TreeMap não usa nem hashCode nem equals, apenas compareTo (se a classe implementar Comparable) ou compare (se você passar um Comparator). Portanto, não adianta implementar hashCode ou equals nesse caso.

  2. Se dois elementos que você quiser inserir em um TreeMap retornarem 0 no compareTo (ou compare), eles são considerados iguais, e isso quer dizer que o segundo elemento não será inserido ou o primeiro será sobreposto (não sei exatamente qual é o comportamento do TreeMap, na verdade).
    Portanto, para evitar que você insira 5 elementos mas apenas 4 apareçam, deixe seu critério de comparação mais completo. Por exemplo, no seu caso, compare por número de quartos e então por cor (se o número de quartos for o mesmo):

public int compare(Object o1, Object o2){  
        Casa c1 = (Casa)o1;  
        Casa c2 = (Casa)o2;  
        if (c1.numQuartos == c2.numQuartos) 
            return c1.cor.compareTo (c2.cor);
        else
            return c1.numQuartos - c2.numQuartos;  
    }
S

jakefrog
Então minha interpretação está correta? Valeu pela resposta.

entanglement
Muito obrigado pela explicação, vou continuar treinando e estudando, mas essa explicação foi suficiente, abraço aos dois e mais uma vez obrigado por respostas tão rápidas.

Sobre a implementação de equals() e hashCode() na verdade eu quis dizer que eles estão sendo implementados na classe que é usada como chave no Map, e assim elas eliminam a duplicidade caso haja.

H

entanglement, por curiosidade.

Um Map não precisa do HashCode e eq para eliminar itens repitidos não?

Basta o Comparator/Comparable que ele faria esse trabalho?

Estava lendo aqui e me esbarrei com esse texto: http://docs.oracle.com/javase/1.4.2/docs/api/java/util/TreeMap.html

As vezes meu inglês me pega…

É sem ofensa tá? Eu não tenho vergonha de falar quando não sei ou tenho dúvidas.

E

hashCode e equals são usados apenas em um HashMap (e seus variantes, como LinkedHashMap ou ConcurrentHashMap.)

Um TreeMap usa apenas compare (ou compareTo) porque ele supõe que dois elementos são iguais quando compare ou compareTo retorna zero. Portanto, ele nem usa o método equals. Satisfeito?

Se tiver dúvidas, tente decifrar os fontes das classes java.util.TreeMap e java.util.HashMap que vêm com o JDK.

S

jakefrog

O que ocorre é o seguinte, quando há ordenação natural, por exemplo quando é um Map de Strings, o equals() e hashCode() estão sobrescritos na classe String, na verdade eu acho que a descrição correta seria: para eliminar as duplicidades a classe que vai ser usada como chave no Map, no meu caso a classe Casa deve sobrescrever estes métodos, se não sobrescrever a classificação vai ocorrer, mas elementos repetidos serão inseridos, além é claro de implementar ou Comparable ou Comparator.

H

entanglement:
hashCode e equals são usados apenas em um HashMap (e seus variantes, como LinkedHashMap ou ConcurrentHashMap.)

Um TreeMap usa apenas compare (ou compareTo) porque ele supõe que dois elementos são iguais quando compare ou compareTo retorna zero. Portanto, ele nem usa o método equals. Satisfeito?

Se tiver dúvidas, tente decifrar os fontes das classes java.util.TreeMap e java.util.HashMap que vêm com o JDK.


Poxa, é assim que vc trata quem te pergunta numa boa? Eu só queria tirar dúvida pois quando fiz SCJP passei com 62% e ainda tenho algumas dúvidas quanto a isso, pois não é algo que uso muito no dia dia.
Desculpe se te incomodei, fica tranquilo que vou sair do seu caminho. [=

@sidney.tavares

Valeu cara, obrigado aí. [=

E

Nem percebi que dei uma patada - deve ser porque sou do signo de Sagitário (que é um centauro, portanto é de certa forma um cavalo, ou seja, tão grosseiro quanto).

Eu só quis dizer que o TreeMap funciona desse jeito, e se precisar verificar por que é que ele é assim, pode-se olhar os fontes diretamente.

Não quis ser rude :slight_smile:

S

entanglement

Cara, como você já respondeu algumas vezes pra mim e sempre ajudou eu meio que conheço o jeito que você responde e sei que não foi pra ofender ninguém…fiz o que você sugeriu e pra falar a verdade eu nem sabia que dava pra ver o código fonte dessas classes, ajudou bastante.

jakefrog

Precisando e eu podendo ajudar estamos aí, às vezes uma coisa que a gente lê parece agressiva mas não é, por isso prefiro falar, mas relaxa que o entanglement é gente boa, abraço.

Criado 22 de dezembro de 2011
Ultima resposta 22 de dez. de 2011
Respostas 9
Participantes 3