自己踩过的set集合的一些坑

自己踩过的set集合的一些坑

1.TreeSet不能添加不同类型的数据
第一遇到这个问题有些诧异,之前一直使用的HashSet就没有问题,当时发现时的场景是在set里添加int和long,报的错是long不能转换为int,后来自己做了个小测试,观看了下源码发现问题的所作,TreeSet是有序的,它添加的数据会调用自己试下的排序方法,不同类型之间的比较会出现异常,导致报错。

  public static void main(String[] args) {
        Set hash = new HashSet();
        hash.add(1);
        hash.add(100L);
        Set tree = new TreeSet();
        tree.add(1);
        tree.add(100L);
    }
}
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
    at java.lang.Long.compareTo(Long.java:54)
    at java.util.TreeMap.put(TreeMap.java:568)
    at java.util.TreeSet.add(TreeSet.java:255)

其本质是因为实现Comparable导致的,只要自己添加自定义类的时候正确实现Comparable可以避免

@Test
    public void test() {
        Set tree = new TreeSet();
        Teacher teacher = new Teacher();
        teacher.setName("111");
        Stu stu = new Stu();
        stu.setName("222");
        tree.add(stu);
        tree.add(teacher);

    }

    class Stu implements Comparable{
        private String name;
        private int num;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getNum() {
            return num;
        }

        public void setNum(int num) {
            this.num = num;
        }

        @Override
        public int compareTo(Object o) {
            return 0;
        }
    }
    class Teacher implements Comparable {
        private String name;
        private char sex;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public char getSex() {
            return sex;
        }

        public void setSex(char sex) {
            this.sex = sex;
        }

        public int compareTo(Stu o) {
            return o.name.compareTo(this.name);
        }

        public int compareTo(Object o) {
            if (o instanceof
                    Stu) {
                Stu stu =(Stu) o;
                return stu.name.compareTo(this.name);
            }
            return 0;
        }
    }

2.set的contains()方法只能比较同类型数据
TreeSet应该不存在这个问题,因为它添加的都是同种数据类型,但是HashSet不是,为什么会出现这种情况呢,其他这个方法的底层还是使用equals方法,只不过set的contains方法不止比较值还比较两个对象的hashcode,所以会导致不同数据类型之间值相同但返回却是false,例如long和int数据的比较

final Node<K,V> getNode(int hash, Object key) {
        Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
        if ((tab = table) != null && (n = tab.length) > 0 &&
            (first = tab[(n - 1) & hash]) != null) {
            if (first.hash == hash && // always check first node
                ((k = first.key) == key || (key != null && key.equals(k))))
                return first;
            if ((e = first.next) != null) {
                if (first instanceof TreeNode)
                    return ((TreeNode<K,V>)first).getTreeNode(hash, key);
                do {
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        return e;
                } while ((e = e.next) != null);
            }
        }
        return null;
    }

 

转载于:https://www.cnblogs.com/yuabnfa/p/10635255.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值