HashSet:
原理:底层是hash表,根据对象的hash值来存储 (hash码:collection.Demo@1540e19d)
判断hash值是否相等的底层实现(JDK1.7):数组+链表
- 首先判断hash值是否相等 (调用hashCode()方法)
- 如果不相等,则将对象存储到hash表中
- 如果相等,则比较是否为同一对象(调用equal()方法)
- 如果部位同一对象,则以链表形式存储
判断hash值是否相等的底层实现(JDK1.8):数组+链表+红黑树
查询复杂度:
- HashSet时根据元素的hashCode来快速定位元素位置的O(1)
- 而使用链表存储后,查询效率性能为O(n)
建议:
- 尽量复写hashCode() ,让其就可以区别各个对象而不需要执行equals() ,例如:return name.hashCode()+age*37;
TreeSet:
特点:可以对存储的元素进行排序(可以让集合自身具有比较性)
实现自然排序方式1:元素实现Comparable接口
实现自然排序方式2:让集合自身具有比较性
- 定义了比较器,让其实现Comparator接口,实现compare(Object o1,Object o2)
- 将比较器对象作为参数传递给TreeSet集合的构造函数
注意:
- 如果两种排序方式存在,则以比较器为主
- 放入集合的对象,其类需要重新hashCode() 和 equal()
public class TreeSetDemo { public static void main(String[] args) { TreeSet ts = new TreeSet(new MyCompare()); ts.add(new Person("abc",1)); ts.add(new Person("abb",2)); ts.add(new Person("bc",3)); ts.add(new Person("cd",2)); ts.add(new Person("abb",3)); Iterator it = ts.iterator(); while(it.hasNext()){ Person p = (Person)it.next(); System.out.println(p.getAge()+":"+p.getName()); } } } class MyCompare implements Comparator { @Override public int compare(Object o1, Object o2) { Person p1 = (Person)o1; Person p2 = (Person)o2; int num = p1.getName().compareTo(p2.getName()); if(num == 0){ if(p1.getAge() > p2.getAge()){ return 1; } if(p1.getAge() < p2.getAge()){ return -1; } return 0; } return num; } }