TreeSet底层源码分析

TreeSet 树结构

  • 特点:

    • 有序
  • 内容要求:

    • 1.包装类
    • 2.引用类型(必须提前写好排序规则)
  • TreeSet中维护了一个TreeMap

  •   public V put(K key, V value) {//TreeMap的添加方法
          Entry<K,V> t = root;//将根节点备份
          if (t == null) {//判断是否是第一次添加
              compare(key, key); // type (and possibly null) check
              root = new Entry<>(key, value, null);//直接将对象封装成Entry对象,赋给根节点
              size = 1;
              modCount++;
              return null;
          }
          int cmp;
          Entry<K,V> parent;
          // split comparator and comparable paths
          Comparator<? super K> cpr = comparator;//将定制排序的对象进行备份
          if (cpr != null) {//是否有定制排序
          	//从根节点就行对比,直到有一个分叉是null为止,找到当前对象添加的位置
              do {
                  parent = t;
                  cmp = cpr.compare(key, t.key);//对比大小
                  if (cmp < 0)
                      t = t.left;//小于走左侧
                  else if (cmp > 0)
                      t = t.right;//大于走右侧
                  else
                      return t.setValue(value);
              } while (t != null);
          }else {
          	//说明没有定制排序    --->  默认就采用自然排序
              if (key == null)//抛空指针异常
                  throw new NullPointerException();
              @SuppressWarnings("unchecked")
                  Comparable<? super K> k = (Comparable<? super K>) key;//将当前对象强转为Comparable
              //依然是从根节点进行对比大小,直到找到自己所在的位置为止
              do {
                  parent = t;
                  cmp = k.compareTo(t.key);//对比大小
                  if (cmp < 0)
                      t = t.left;//小于走左侧
                  else if (cmp > 0)
                      t = t.right;//大于走右侧
                  else//说明在当前树节点中找到和当前对象相同的数据了,则对value值进行覆盖
                      return t.setValue(value);
              } while (t != null);
          }
          
          
          Entry<K,V> e = new Entry<>(key, value, parent);//将当前对象封装成一个Entry对象
          if (cmp < 0)
              parent.left = e;//将当前Entry对象放在parent的左侧
          else
              parent.right = e;//将当前Entry对象放在parent的右侧
          fixAfterInsertion(e);
          size++;
          modCount++;
          return null;
      }
    
  • 2、

    • TreeSet无序的原因
      • 有一个大小排序机制
        • Comparable --> int compareTo(Object obj)
        • Comparator --> int compare(Object o1,Object o2)
        • 大于返回正数、等于返回0、小于负数
    • TreeSet不可重复的原因
      • Comparable --> int compareTo(Object obj)
      • Comparator --> int compare(Object o1,Object o2)
      • 如果返回的是0,则进行value值的覆盖
  • 3、 面试题

    • a. HashSet如何实现的无序和不可重复
      • 利用长度&hashcode决定下标
      • 利用hashcode和equals判断重复
    • b. TreeSet如何实现的无序(无序是指不以添加顺序为输出顺序)和不可重复
      • 有定制排序机制(Comparable --> int compareTo(Object obj)或Comparator --> int compare(Object o1,Object o2))
      • 排序是发现相同的就用新的覆盖掉旧的
    • c. TreeSet中如果定制排序和自然排序同时存在,以谁为准?
      • 定制排序为准(代码中先判断了是否存在定制排序,如果不存在在进入自然排序的方法)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值