Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

Porque com TreeSet o contains funciona sem sobrescrever o hashcode()?

Porque nesse caso do TreeSet passando um Comparator no construtor o método contains funciona mesmo sem sebrescrever o hashcode()?

//rec3 = rec4 = rec5
System.out.println("A lista recibos contém rec5? " + recibos.contains(rec5));

Minha implementação:

package br.com.alura;

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

public class TesteTreeSet {

    public static void main(String[] args) {

        Recibo rec1 = new Recibo();
        rec1.setNome("Recibo1");
        rec1.setNro(1);
        Recibo rec2 = new Recibo();
        rec2.setNome("Recibo2");
        rec2.setNro(1);
        Recibo rec3 = new Recibo();
        rec3.setNome("Recibo3");
        rec3.setNro(1);
        Recibo rec4 = new Recibo();
        rec4.setNome("Recibo3");
        rec4.setNro(1);

        Comparator<Recibo> comparator = new Comparator<Recibo>() {

            @Override
            public int compare(Recibo o1, Recibo o2) {

                boolean ordemNatural = true;

                if (o1.getNome().equals(o2.getNome()) && o1.getNro() == o2.getNro()) {
                    return 0;
                } else if (ordemNatural) {
                    return 1;
                } else {
                    return -1;
                }
            }
        };

        Set<Recibo> recibos = new TreeSet<>(comparator);
        recibos.add(rec1);
        recibos.add(rec2);
        recibos.add(rec3);
        recibos.add(rec4);


        System.out.println(recibos);

        Recibo rec5 = new Recibo();
        rec5.setNome("Recibo3");
        rec5.setNro(1);

        //rec3 = rec4 = rec5
        System.out.println("A lista recibos contém rec5? " + recibos.contains(rec5));

        System.out.println("O rec4.hashcode() == rec5.hashcode()? " + (rec4.hashCode() == rec5.hashCode()));
    }

}

class Recibo {

    private String nome;
    private int nro;

    public String getNome() {
        return nome;
    }

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

    public int getNro() {
        return nro;
    }

    public void setNro(int nro) {
        this.nro = nro;
    }

    @Override
    public String toString() {
        return "Recibo [nome=" + nome + ", nro=" + nro + "]";
    }

}
5 respostas

Oi Daniel, tudo bem?

O TreeSet, diferentemente do HashSet não utiliza o hashcode(), apenas o equals()

Tem como vc me mostrar como chegou a essa conclusão da mesma forma que mostrou no tópico abaixo? Tentei, mas não consegui... https://cursos.alura.com.br/forum/topico-onde-esta-escrito-a-diferenca-entre-usar-contains-com-list-vs-set-100649

Tentando seguir o que vc fez no outro tópico cheguei até o ponto mostrado abaixo:

public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }
public TreeMap(Comparator<? super K> comparator) {
        this.comparator = comparator;
    }
    private final Comparator<? super K> comparator;
    int compare(T o1, T o2);  // Dentro da classe Comparator

Alguém?

solução!

O HashSet usa por baixo um HashMap:

HashSet .java

    public boolean containsKey(Object key) {
        return getNode(hash(key), key) != null; // chama o hashCode
    }

O TreeSet usa por baixo um TreeMap, que não utiliza o hashcode:

TreeMap.java

    final Entry<K,V> getEntry(Object key) {
        // Offload comparator-based version for sake of performance
        if (comparator != null)
            return getEntryUsingComparator(key);
        if (key == null)
            throw new NullPointerException();
        @SuppressWarnings("unchecked")
            Comparable<? super K> k = (Comparable<? super K>) key;
        Entry<K,V> p = root;
        while (p != null) {
            int cmp = k.compareTo(p.key);
            if (cmp < 0)
                p = p.left;
            else if (cmp > 0)
                p = p.right;
            else
                return p;
        }
        return null;
    }

Massa. Vlw demais.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software