我想知道当javadocs for TreeSet
说是什么意思
此类实现由树状图实例支持的 Set 接口?
在下面的示例中,我还没有实现 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
如何对对象进行哈希处理?
我想你提出了两个问题。
1,为什么你的代码有效?
正如 Avi 在这个主题上所写:
当你不重写 hashCode() 方法时,你的类会从 Object 继承默认的 hashCode() 方法,它为每个对象提供不同的哈希代码。这意味着 t1 和 t2 有两个不同的哈希码,即使您比较它们,它们也会相等。根据特定的哈希图实现,地图可以自由地单独存储它们。
这意味着它不必单独存储它们,但可以。试试这个代码:
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")));
我的输出如下:
true
true
true
false
false
false
false
false
false
这意味着他们中的一些人在那里,其中一些人没有。
2,当 javadocs for Treeset 说"这个类实现了 Set 接口,由树状图实例支持"时,这意味着什么?
这意味着 java 1.7 中的 TreeSet 类如下所示:
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.
这意味着在 TreeSet 类下有一个映射,并且有很多方法只委托给它。
我希望我能提供帮助。
TreeSet 内部确实使用 TreeMap。树状图不需要为关键对象实现哈希代码和等于方法。树状图内部使用红黑树,这是一个自平衡的二叉搜索树。此树中的顺序通过使用 compareTo 方法(键对象实现可比较接口)或比较方法(假设在构造树图时定义了比较器,在本例中实际上是 TreeSet)来维护。希望它能清除。
TreeSet 内部使用 TreeMap 对象 'm' 将对象存储为键值对,这意味着调用
set.add(x);
内部调用树状图的 put 方法:
public boolean add(E e) {
return m.put(e, PRESENT)==null;
}
现在,如果提供了比较器,则在内部调用放置方法,或者在您的情况下使用ComparisonLogic类"compareTo"方法。
它从不使用等于或哈希码显式使用,而是使用 compareTo(Object o1)(在实现 Comparable 时提供)或 compare(Object o1,object o2)(在实现 Comparator 时提供)方法来确定集合中是否存在 Object。
因此,要回答您的问题,不需要实现hashcode()方法,除非您在比较(比较或比较)方法实现中使用它。
您的ComparisonObject
正在使用Object
上定义的hashCode
方法。尝试添加许多不同的ComparisonLogic
,两个字段的值相同,看看会发生什么。