TreeSet的内部使用TreeMap的,因此,它是需要实现hashCode方法使用TreeSet的时候?

问题描述 投票:8回答:4

我想知道这意味着什么时TreeSet的javadoc说

此类实现Set接口,由TreeMap实例支持?

在下面的例子中,我还没有实现的Hashcode方法,仍然是工作按照预期即它能够将对象进行排序。请注意,我特意没有实现一致的Equals实施检查TreeSet行为。

import java.util.TreeSet;


public class ComparisonLogic implements Comparable<ComparisonLogic>{

String field1;
String field2;

public String toString(){
    return field1+" "+field2;
}

ComparisonLogic(String field1,String field2){
    this.field1= field1;
    this.field2= field2;

}
public boolean equal(Object arg0){
    ComparisonLogic obj = (ComparisonLogic) arg0; 

    if(this.field1.equals(obj.field1))
        return true;
    else
        return false;
}

public int compareTo(ComparisonLogic arg0){
    ComparisonLogic obj = (ComparisonLogic) arg0;   
    return this.field2.compareToIgnoreCase(obj.field2);
}

/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub

    ComparisonLogic x = new ComparisonLogic("Tom", "jon");
    ComparisonLogic y = new ComparisonLogic("Tom", "Ben");
    ComparisonLogic z = new ComparisonLogic("Tom", "Wik");

    TreeSet<ComparisonLogic> set = new TreeSet<ComparisonLogic>();
    set.add(x);
    set.add(y);
    set.add(z);
    System.out.println(set);
}

}

这个例子打印[Tom Ben, Tom jon, Tom Wik]。因此,它是基于compareTo方法排序和hashcode()方法看起来在这种情况下不显着。然而,Treeset由TreeMap的支持,所以如果内部是TreeMap用于排序,TreeMap是如何散列对象?

java collections hashcode treemap treeset
4个回答
7
投票

我认为你是冒充的两个问题。

1,为什么工作你的代码?

截至qazxsw POI话题qazxsw POI写:

当你不重写的hashCode()方法,你的类继承自对象的默认的hashCode()方法,这给每一个对象不同的散列码。这意味着,t1和t2有两个不同的散列码,即使是你对它们进行比较,他们是平等的。根据特定的HashMap实现,地图可以自由地分开存放。

这意味着它不必分开存放,但它可能。试试这个代码:

Avi

对我来说,产量为以下几点:

this

这意味着他们中的一些人有一些人没有。

2,这意味着什么时TreeSet中的javadoc说:“此类实现Set接口,由TreeMap实例支持”?

这意味着,在Java 1.7 TreeSet类如下所示:

TreeSet<ComparisonLogic> set = new TreeSet<ComparisonLogic>();
    set.add(new ComparisonLogic("A", "A"));
    set.add(new ComparisonLogic("A", "B"));
    set.add(new ComparisonLogic("A", "C"));
    set.add(new ComparisonLogic("B", "A"));
    set.add(new ComparisonLogic("B", "B"));
    set.add(new ComparisonLogic("B", "C"));
    set.add(new ComparisonLogic("C", "A"));
    set.add(new ComparisonLogic("C", "B"));
    set.add(new ComparisonLogic("C", "C"));
    set.add(new ComparisonLogic("A", "A"));

    System.out.println(set.remove(new ComparisonLogic("A", "A")));
    System.out.println(set.remove(new ComparisonLogic("A", "B")));
    System.out.println(set.remove(new ComparisonLogic("A", "C")));
    System.out.println(set.remove(new ComparisonLogic("B", "A")));
    System.out.println(set.remove(new ComparisonLogic("B", "B")));
    System.out.println(set.remove(new ComparisonLogic("B", "C")));
    System.out.println(set.remove(new ComparisonLogic("C", "A")));
    System.out.println(set.remove(new ComparisonLogic("C", "B")));
    System.out.println(set.remove(new ComparisonLogic("C", "C")));

这意味着,有一个地图TreeSet类下面有很多的它仅委托给它的方法。

我希望我能帮助。


1
投票

这是事实,TreeSet的内部使用TreeMap的。 TreeMap中并不需要具备的hashCode和equals重点对象实现的方法。 TreeMap的内部使用红黑树是一种自平衡二叉搜索树。在此树的顺序通过使用compareTo方法(密钥对象实现可比接口)或比较方法保持(在构造TreeMap的,在这种情况下为TreeSet中实际提供的比较器被定义)。希望它清除。


0
投票

true true true false false false false false false 使用上public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable { /** * The backing map. */ private transient NavigableMap<E,Object> m; TreeSet(NavigableMap<E,Object> m) { this.m = m; } ... (lots of other code) public boolean contains(Object o) { return m.containsKey(o); } etc. 定义的ComparisonObject方法。尝试添加一些不同的hashCode的,具有两个领域相同的值,看看会发生什么。


0
投票

TreeSet中内部使用TreeMap的对象的“m”为存储对象作为键 - 值对,这意味着该呼叫

Object

内部调用树形图put方法:

ComparisonLogic

现在把方法在内部调用任何比较,如果提供比较或者在你的情况下使用ComparisonLogic类“的compareTo”方法。

它绝不会使用等号或哈希码明确而使用的compareTo(对象01)(在实施可比提供)或比较(对象O1,O2的对象)(提供同时实现比较器)方法来确定对象的所述组中的存在。

所以回答你的问题,除非你在你的相比,在使用它来实现hashCode()方法方法不要求(或比较的compareTo)方法实现。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.