TreeSet和HashSet的不同之处(也是TreeMap和HashMap的不同之处)
1)TreeSet和HashSet都是利用对应的Map的key值进行数据保存(TreeMap和HashMap,所以map的value肯定是可以为null的)
2)TreeMap是使用红黑树进行数据保存,HashMap是进行hash计算后存入数组+链表(或红黑树)
以上2点,大家只要学习过,都会记得,但是我要说的是,TreeSet保存的数据,必须是继承Comparable接口或者要设定好Comparator比较器的,就是说:TreeSet的数据必须是可以比较的,而HashMap是不用这样的设置的
HashSet比较两个对象的数值是否一致的标志是:两个值的equals后是否相同(1、是可以为null的,hashCode为0;2、HashSet实验到红黑树时候,也是要比较大小的,依次是比较hash值->compare->getClass().getName()->System.identityHashCode(identityHashCode是根据对象的地址计算得到的,所以任何两个不同的对象的identityHashCode值总是不相等),如果compare比较的结果是0不是按相同处理,而是进一步的比较,只要equals不同,就一定要比出胜负)
可以为null的,hashCode为0)
TreeSet比较两个对象的数值是否一致的标志是:两个值的compare后是否为0(因为要compare比较,所以TreeSet不能插入null)
所以,自然就会出现,相同一个list,放入不同的set中,得到的set的结果是不同的
如何才能避免这个问题呢,只需要保证实现了compareTo方法,就有必要实现equals方法,而且保证两个方法是同步的(即要么同时不等,要么同时相等)
//下面是测试例子compareTo只比较k值,equals只比较t值
public static void main(String[] args) {
HashSet<NNNode> hashSet = new HashSet();
TreeSet<NNNode> treeSet = new TreeSet<>();
List<NNNode> list = getList();
for (NNNode nnNode : list) {
hashSet.add(nnNode);
treeSet.add(nnNode);
}
System.out.println(hashSet.size());
System.out.println(treeSet.size());
System.out.println(hashSet);
System.out.println(treeSet);
}
private static List<NNNode> getList() {
List<NNNode> list = new ArrayList<>();
list.add(new NNNode(0, 0));
list.add(new NNNode(1, 0));
list.add(new NNNode(2, 0));
list.add(new NNNode(3, 0));
list.add(new NNNode(4, 0));
list.add(new NNNode(0, 1));
list.add(new NNNode(0, 2));
list.add(new NNNode(0, 3));
return list;
}
static class NNNode implements Comparable<NNNode> {
int k;
int t;
public NNNode(int k, int t) {
this.k = k;
this.t = t;
}
@Override
public int hashCode() {
return 0;
}
@Override
public int compareTo(NNNode o) {
return k - o.k;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o instanceof NNNode) {
return t == ((NNNode) o).t;
}
return false;
}
@Override
public String toString() {
return "NNNode{" +
"k=" + k +
", t=" + t +
'}';
}
}
结果就是
4
5
[NNNode{k=0, t=0}, NNNode{k=0, t=1}, NNNode{k=0, t=2}, NNNode{k=0, t=3}]
[NNNode{k=0, t=0}, NNNode{k=1, t=0}, NNNode{k=2, t=0}, NNNode{k=3, t=0}, NNNode{k=4, t=0}]