JavaSE——集合框架一(6/7)-Set系列集合:LinkedHashSet的底层原理、TreeSet集合(介绍,自定义排序规则,排序示例)

简介: JavaSE——集合框架一(6/7)-Set系列集合:LinkedHashSet的底层原理、TreeSet集合(介绍,自定义排序规则,排序示例)

LinkedHashSet的原理

之前我们了解到LinkedHashSet的特点:

  • 有序、不重复、无索引

它的底层原理

  • 依然是基于哈希表(数组、链表、红黑树)实现的。
  • 但是,它的每个元素都额外的多了一个双链表的机制记录它前后元素的位置。

当有要填入的元素的哈希值一样时:


同时,双链表的机制代表着它有着头指针与尾指针,分别指向第一个元素和最后一个元素:


TreeSet集合

介绍

  • 特点:不重复、无索引、可排序(默认升序排序,按照元素的大小,由小到大排序)
  • 底层是基于红黑树实现的排序。
import java.util.Set;
import java.util.TreeSet;
 
public class SetDemo4 {
    public static void main(String[] args) {
        Set<Integer> integerSet = new TreeSet<>();
        integerSet.add(135);
        integerSet.add(13);
        integerSet.add(113);
        integerSet.add(255);
        integerSet.add(255);
        System.out.println(integerSet);
    }
}

运行结果:


注意:

  • 对于数值类型:Integer,Double,默认按照数值本身的大小进行升序排序。
  • 对于字符串类型:默认按照首字符的编号升序排序。
  • 对于自定义类型如Student对象,TreeSet默认是无法直接排序的。

例如:

1. imimport java.util.Set;
import java.util.TreeSet;
 
public class SetDemo4 {
    public static void main(String[] args) {
        Set<Student> students = new TreeSet<>();
        students.add(new Student("至尊宝",26,165.5));
        students.add(new Student("蜘蛛精",23,169.7));
        students.add(new Student("牛魔王",22,183.5));
        students.add(new Student("紫霞",22,169.8));
        System.out.println(students);
    }
}

运行报错:


这时就需要用到我们熟悉的自定义排序规则了,

自定义排序规则

  • TreeSet集合存储自定义类型的对象时,必须指定排序规则,支持如下两种方式来指定比较规则。

方式一

让自定义的类(如学生类)实现Comparable接口,重写里面的compareTo方法来指定比较规则。

方式二


通过调用TreeSet集合有参数构造器,可以设置Comparator对象(比较器对象,用于指定比较规则)。

public TreeSet(Comparator<? super E>  comparator)

排序示例

第一种自定义排序方式让类实现Comparable接口,并重写里面的compareTo方法



此时再运行一次代码,得到结果:



按年龄升序排序,其中有两个年龄相同的对象,重复的不进行存储。

第二种自定义排序方式调用TreeSet集合有参数构造器,设置Comparator对象



当两种自定义排序都存在时,TreeSet会就近选择自己自带的比较器对象进行排序

运行结果:


因为身高没有重复的,所以都存储进去了。

Lambda简化



最后回顾总结一下,两种方式中,关于返回值的规则:


  • 如果认为第一个元素>第二个元素返回正整数即可。
  • 如果认为第一个元素<第二个元素返回负整数即可。
  • 如果认为第一个元素=第二个元素返回o即可,此时Treeset集合只会保留一个元素,认为两者重复。
  • 注意:如果类本身有实现Comparable接口,TreeSet集合同时也自带比较器,默认使用集合自带的比较器排序。



END



目录
相关文章
|
1天前
|
JavaScript API 索引
JS【详解】Set 集合 (含 Set 集合和 Array 数组的区别,Set 的 API,Set 与 Array 的性能对比,Set 的应用场景)
JS【详解】Set 集合 (含 Set 集合和 Array 数组的区别,Set 的 API,Set 与 Array 的性能对比,Set 的应用场景)
6 0
|
2天前
|
存储 NoSQL Java
Redis10------Set类型,存在着无序的特征存储的顺序和插入的顺序是无关的,set集合的一大特点是不可重复,在redis中支持交集插集等特殊功能,好友列表,共同关注等等
Redis10------Set类型,存在着无序的特征存储的顺序和插入的顺序是无关的,set集合的一大特点是不可重复,在redis中支持交集插集等特殊功能,好友列表,共同关注等等
|
3天前
|
索引
ArrayList集合常用方法,.set可以用来生成图片和赋值命名,array.remove(1),array.set(1,“xxxx”)可以修改指定位置,array.size可以获取元素的个数
ArrayList集合常用方法,.set可以用来生成图片和赋值命名,array.remove(1),array.set(1,“xxxx”)可以修改指定位置,array.size可以获取元素的个数
|
3天前
|
存储 语音技术 Python
语音识别,函数综合案例,黑马ATM,/t/t一个对不齐,用两个/t,数据容器入门,数据容器可以分为列表(list)、元组(tuple)、字符串(str)、集合(set)、字典(dict)
语音识别,函数综合案例,黑马ATM,/t/t一个对不齐,用两个/t,数据容器入门,数据容器可以分为列表(list)、元组(tuple)、字符串(str)、集合(set)、字典(dict)
|
12天前
|
Dart
Dart之集合详解(List、Set、Map)
Dart之集合详解(List、Set、Map)
14 1
|
17天前
|
存储 JavaScript 前端开发
JavaScript进阶-Map与Set集合
【6月更文挑战第20天】JavaScript的ES6引入了`Map`和`Set`,它们是高效处理集合数据的工具。`Map`允许任何类型的键,提供唯一键值对;`Set`存储唯一值。使用`Map`时,注意键可以非字符串,用`has`检查键存在。`Set`常用于数组去重,如`[...new Set(array)]`。了解它们的高级应用,如结构转换和高效查询,能提升代码质量。别忘了`WeakMap`用于弱引用键,防止内存泄漏。实践使用以加深理解。
|
12天前
|
Go
go语言map、实现set
go语言map、实现set
14 0
|
12天前
|
存储 消息中间件 算法
Java中的集合框架详解:List、Set、Map的使用场景
Java中的集合框架详解:List、Set、Map的使用场景
|
5天前
|
存储 JavaScript 前端开发
JavaScript编码之路【ES6新特性之 Symbol 、Set 、Map、迭代器、生成器】(二)
JavaScript编码之路【ES6新特性之 Symbol 、Set 、Map、迭代器、生成器】(二)
9 1
|
11天前
|
存储 自然语言处理 C++
【C++航海王:追寻罗杰的编程之路】set|map|multiset|multimap简单介绍
【C++航海王:追寻罗杰的编程之路】set|map|multiset|multimap简单介绍
14 0
【C++航海王:追寻罗杰的编程之路】set|map|multiset|multimap简单介绍