自己踩过的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; }