TreeSet和HashSet的不同之处(也是TreeMap和HashMap的不同之处)

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 hashSet = new HashSet();
    TreeSet treeSet = new TreeSet<>();
    List 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 getList() {
    List 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 {
    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}]

你可能感兴趣的:(集合)