HashSet,TreeSet是怎么保证元素唯一性的?

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

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值