当前位置: 首页 > 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.lryc.cn/news/460624.html

相关文章:

  • 【idea技巧篇】idea的类注释和方法注释模版自定义设置
  • 【Kubernetes① 基础】一、容器基础
  • 计算机网络第1章(概述)万字笔记详细版
  • 每日一练算法题(堆串的基本操作StrReplace(S, T, V))
  • IRP默认最小流程
  • 【全网最全】AI产品经理面试高频100题答案解析
  • VLLM实现大模型服务的部署
  • Java 基数排序
  • 红帽发送邮件操作
  • 学习记录:js算法(六十一):添加与搜索单词 - 数据结构设计
  • Jetpack-ObservableField实现双向绑定
  • STARnak, LTR 模型笔记
  • 【数据结构】:破译排序算法--数字世界的秩序密码(二)
  • 2024年《生成式ai大模型》都学什么内容呢?
  • kubernetes自定义pod启动用户
  • C4T避风型电动采光排烟天窗(图集09J621-2)
  • 多态常见面试问题
  • 案例-登录认证(上)
  • 对BSV区块链下一代节点Teranode的答疑解惑(上篇)
  • vue父子组件传参的方法
  • 关于this指针
  • 机器学习西瓜书
  • 如何使用 Puppeteer 和 Browserless 运行自动化测试?
  • python菜鸟知识
  • GPT4o,GPTo1-preview, 拼
  • 论文笔记:Pre-training to Match for Unified Low-shot Relation Extraction
  • 一篇文章带你快速了解linux中关于信号的核心内容
  • openEuler、Linux操作系统常见操作-(6)如何登录Linux
  • Python基础语法条件
  • 006-MAVEN 的使用