当前位置: 首页 > news >正文

JavaSE——集合7:Set接口实现类—TreeSet

目录

一、TreeSet基本介绍

二、TreeSet核心方法

三、TreeSet排序方法

四、TreeSet源码解析

1.无参构造时,底层是创建TreeMap对象

2.有参构造时,底层也创建TreeMap对象

3.执行add方法

4.执行put方法 


一、TreeSet基本介绍

  1. TreeSet是 Java 集合框架中的一个有序集合类,其底层实现主要依赖于红黑树(Red-Black Tree)这一数据结构
  2. TreeSet的底层是通过TreeMap实现的
  3. 当我们使用无参构造器,创建TreeSet时,仍然是无序的
  4. 如果希望添加的元素,按照字符串大小来排序,使用TreeSet 提供的一个构造器,可以传入一个比较器(匿名内部类)并指定排序规则

二、TreeSet核心方法

  1. add(E e):向TreeSet中添加一个元素。如果元素已经存在,则不会添加该元素,并返回false;否则,添加元素并返回true。
  2. remove(Object o):从TreeSet中移除一个元素。如果元素存在,则移除该元素并返回true;否则,返回false。
  3. contains(Object o):检查TreeSet是否包含指定的元素。如果包含,则返回true;否则,返回false。
  4. size():返回TreeSet中元素的数量。
  5. isEmpty():检查TreeSet是否为空。如果为空,则返回true;否则,返回false。
  6. first():返回TreeSet中的第一个元素(即最小的元素)。如果TreeSet为空,则抛出NoSuchElementException异常。
  7. last():返回TreeSet中的最后一个元素(即最大的元素)。如果TreeSet为空,则抛出NoSuchElementException异常。
  8. headSet(E toElement):返回一个视图,该视图包含小于指定元素的元素。这个视图是TreeSet的一个子集合,对原TreeSet的修改会影响这个视图,反之亦然。
  9. tailSet(E fromElement):返回一个视图,该视图包含大于或等于指定元素的元素。这个视图同样是TreeSet的一个子集合。
  10. subSet(E fromElement, E toElement):返回一个视图,该视图包含从指定起始元素(包括)到指定结束元素(不包括)之间的元素。这个视图也是TreeSet的一个子集合。

三、TreeSet排序方法

public class TreeSet_ {public static void main(String[] args) {// 默认排序:无序TreeSet treeSet = new TreeSet();// [a, jack, marry, rose, tom]// 按照字符从小到大排序TreeSet treeSet = new TreeSet((o1, o2) -> ((String) o1).compareTo((String) o2));// [a, jack, marry, rose, tom]// 按照字符从大到小排序TreeSet treeSet = new TreeSet((o1, o2) -> ((String) o2).compareTo((String) o1));// [tom, rose, marry, jack, a]// 按照长度从小到大排序TreeSet treeSet = new TreeSet((o1, o2) -> (((String) o1).length()) - (((String) o2).length()));// [a, tom, jack, marry]// 按照长度从大到小排序TreeSet treeSet = new TreeSet((o1, o2) -> (((String) o2).length())-(((String) o1).length()));// [marry, jack, tom, a]/*这个比较器会计算两个字符串 o1 和 o2 的长度差,并返回这个差值作为比较结果。如果结果为负数,则 o1 被认为小于 o2;如果结果为正数,则 o1 被认为大于 o2;如果结果为0,则两个元素相等(但在 TreeSet 中,相等的元素只会被存储一个)。分析添加到 TreeSet 中的字符串:"jack":长度为4"tom":长度为3"rose":长度为4"marry":长度为5"a":长度为1根据比较器的逻辑,这些字符串会被按照长度排序。由于 "jack" 和 "rose" 长度相同(都是4),它们在排序时被认为是相等的。但是,TreeSet 不允许存储重复的元素,因此尽管 "jack" 和 "rose" 内容不同,但由于长度相同,在添加到 TreeSet 时,"rose" 会被视为与已存在的 "jack" 相等,并且不会被添加进去。这就是为什么在遍历 TreeSet 时,"rose" 没有出现的原因。*/// 区分长度相同但内容不同的字符串TreeSet treeSet = new TreeSet((o1, o2) -> {int lengthComparison = Integer.compare(((String) o1).length(), ((String) o2).length());if (lengthComparison != 0) {return lengthComparison;} else {return ((String) o1).compareTo(((String) o2));}});// [a, tom, jack, rose, marry]treeSet.add("jack");treeSet.add("tom");treeSet.add("rose");treeSet.add("marry");treeSet.add("a");System.out.println(treeSet);}
}

四、TreeSet源码解析

1.无参构造时,底层是创建TreeMap对象

public TreeSet() {this(new TreeMap<>());
}

2.有参构造时,底层也创建TreeMap对象

把传入的比较器对象,赋给了TreeSet的底层的TreeMap的属性this.comparator 

public TreeMap(Comparator<? super K> comparator) {this.comparator = comparator;
}

3.执行add方法

因为TreeSet不关注value,所以会有一个静态常量对象放在value的位置 

private static final Object PRESENT = new Object();public boolean add(E e) {return m.put(e, PRESENT)==null;
}3.执行put方法:存放数据

4.执行put方法 

public V put(K key, V value) {Entry<K,V> t = root;if (t == null) {compare(key, key); // type (and possibly null) checkroot = new Entry<>(key, value, null);size = 1;modCount++;return null;}int cmp;Entry<K,V> parent;// split comparator and comparable pathsComparator<? super K> cpr = comparator;if (cpr != null) { // cpr 就是匿名内部类(对象)do {parent = t;// 动态绑定到匿名内部类(对象)comparecmp = cpr.compare(key, t.key);if (cmp < 0)t = t.left;else if (cmp > 0)t = t.right;else  // 如果相等,即返回0,这个Key就没有加入// value仍然是原来的PRESENT来占位return t.setValue(value);} while (t != null);}

http://www.mrgr.cn/news/51072.html

相关文章:

  • std::function的概念和使用方法
  • 卡尔曼滤波(Kalman Filter)MATLAB代码
  • Codeforces Round 978 (Div. 2) C. Gerrymandering
  • Go语言基础学习(Go安装配置、基础语法)
  • 【AI论文精读5】知识图谱与LLM结合的路线图-P2
  • OpenAI 公布了其新 o1 模型家族的元提示(meta-prompt)
  • 38. 外观数列
  • Python机器学习数据清洗到特征工程策略
  • K8s的储存
  • 音视频入门基础:FLV专题(15)——Video Tag简介
  • Vue中计算属性computed—(详解计算属性vs方法Methods,包括案例+代码)
  • (三)Python变量
  • python 位运算 笔记
  • SpringTask的学习
  • 高阶数据结构与算法——红黑树の奥秘
  • 记忆化递归讲解和【题解】—— [NOIP2001 普及组] 数的计算
  • Mamba学习笔记(1)——原理基础
  • 超强的开源OCR工具Surya更新了表识别功能!GitHub收藏人数超过1万。
  • Java微信支付接入(9) - API V3 微信支付查单API
  • 地平线与英伟达工具链 PTQ 工具功能参数对比与实操