java Set容器 结论+源码分析 总结 (2)

 内容随时更新,最大程度的分析每个方法 

Set

2、HashSet 

1、是一个无序的集合,且不允许存放相同的数据,且可以存放null值

2、低层调用的是HashMap的put方法

3、低层的数据结构是:数组+链表+红黑树

基本用法: 

    @Test
    public void hashSetTest() {

        //创建一个HashSet集合
        HashSet<Integer> integers = new HashSet<Integer>();
        Random random = new Random();

        //储存数据
        for (int i = 0; i < 10; i++) {
            int i1 = random.nextInt(20);

            //输出生成的随机数
            System.out.print(i1+" ");//13 0 18 8 0 3 9 6 9 17

            //添加数据到HashSet集合里面
            integers.add(i1);
        }
        System.out.println();
        //生成迭代器取出数据
        Iterator<Integer> iterator = integers.iterator();

        while (iterator.hasNext()) {
            System.out.print(iterator.next()+" ");//0 17 18 3 6 8 9 13
        }
    }

构造方法:

有四种构造器能给我所用,所以有四种创建一个HashSet容器的方法

 方法源码:

add源码

    public boolean add(E e) {
        return map.put(e, PRESENT)==null;//这个map是HashMap类型
    }

    //这是HashMap的put的方法
    public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }

    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);//调用hashCode()生成一个哈希值,主要的作用是用来判断储存的key是否已经储存了,如果哈希值不相等,说明key值还没有储存,如果哈希相等也不能说明key是相同的,这里还要跟哈希值相等的key进行==(比较引用值)来验证key是否是相同的
    }

跟进putVal源码 :逐个分析putVal里面的语句

跟进resize()方法,查看调用resize()初始化操作: 

 回到putVal方法中:

 

链表转换树形数据结构操作:treeifyBin(tab, hash);

跟进查看源码

调用treeify: 源码跟进

 里面调用了三个方法:comparableClassFor、compareComparables、tieBreakOrder,跟进源码:

 总结:comparableClassFor方法,该方法表示的是,存放的key的类型一定要实现Comparable接口,且里面指定的泛型的类型一定要和key的类型相同,如果相同的话,直接返回key的class类型,如果不相同的,则直接返回null.

回到treeify: 源码中

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值