HashSet利用的是hashmap中的key不能唯一的原则。通过判断元素的hashCode值是否相同。如果相同,还会继续判断元素的equals方法,是否为true。
TreeSet底层保证元素唯一性是通过Comparable或者Comparator接口实现。
public class Order {
private String orderNo;
private String userId;
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
}
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
public class TestSort {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<Order> orderList = new ArrayList<Order>();
Order order1 = new Order();
order1.setOrderNo("123");
order1.setUserId("bb123");
orderList.add(order1);
Order order2 = new Order();
order2.setOrderNo("123");
order2.setUserId("aa123");
orderList.add(order2);
Order order3 = new Order();
order3.setOrderNo("33");
order3.setUserId("aa123");
orderList.add(order3);
Set<Order> set = new TreeSet<Order>(new Comparator<Order>() {
public int compare(Order a, Order b) {
return a.getUserId().compareTo(b.getUserId()); //order2和order3的userId一样,所以order3不会被添加到TreeSet中
}
});
set.addAll(orderList);
for(Order data : set){
System.out.println(data.getOrderNo() + ":" + data.getUserId());
}
}
}
执行结果:
123:aa123
123:bb123
HashSet添加元素过程
我们向HashSet中添加元素a,首先调用元素a所在类的hashcode()方法,计算元素a的哈希值,次哈希值接着通过某种算法计算出在HashSet底层数组中的存放位置(即:索引位置),判断数组此位置是否已经有元素
如果此位置上没有其它元素,则元素a添加成功。--->情况1
如果此位置上有其它元素b(或以链表形式存在的多个元素),则比较元素a与元素b的hash值
如果hash值不同,则元素a添加成功。 --->情况2
如果hash相同,进而需要调用元素a所在类的equals()方法:
equals()放回true,元素a添加失败
equals()返回false,则元素a添加成功。 --->情况3
对于添加成功的情况2和情况3而言:元素a与已经存在指定索引位置上数据以链表的形式存储。
jdk7:元素a放到数组中,指向原来的元素
jdk8:原来的元素在数据中,指向元素a
总结:七上八下
HashSet底层:数组+链表的解构。
LinkedHashSet的使用
LinkedHashSet作为HashSet的子类,在添加数据的同时,每个数据还维护了两个引用,记录此数据前一个数据和后一个数据
优点:对于频繁的遍历操作,LinkedHashSet效率高于HashSet
向TreeSet中添加的数据,要求是相同类的对象
两种排序方式:自然排序(实现Comparable接口)和定制排序(Comparator)
自然排序中,比较两个对象是否相同的标准为:compareTo()返回0,不再是hashcode和equals()
定制排序中,比较两个对象是否相同的标准为:compare()返回0,不再是hashcode和equals