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



目录
相关文章
|
5天前
|
存储 JavaScript 前端开发
JavaScript进阶-Map与Set集合
【6月更文挑战第20天】JavaScript的ES6引入了`Map`和`Set`,它们是高效处理集合数据的工具。`Map`允许任何类型的键,提供唯一键值对;`Set`存储唯一值。使用`Map`时,注意键可以非字符串,用`has`检查键存在。`Set`常用于数组去重,如`[...new Set(array)]`。了解它们的高级应用,如结构转换和高效查询,能提升代码质量。别忘了`WeakMap`用于弱引用键,防止内存泄漏。实践使用以加深理解。
|
13天前
|
存储 安全 Java
Java集合详解:Set, Map, Vector, List的对比与联系
Java集合框架核心包括List、Set、Map和Vector。List允许重复元素,如ArrayList(适合读取)和LinkedList(适合插入删除)。Set不允许重复,有HashSet(无序)和TreeSet(排序)。Map存储键值对,HashMap(无序)和TreeMap(排序)。Vector是线程安全的ArrayList替代品,但在多线程环境下使用。选择集合类型应根据应用场景,如有序、无序、键值对需求及线程安全考虑。
|
16天前
|
存储 安全 Java
Java 集合(List、Set、Map 等)相关问答归纳再整理
HashMap 中使用键对象来计算 hashcode 值 HashSet 使用成员对象来计算 hashcode 值,对于两个对象来说hashcode 可能相同,所以 equals() 方法用来判断对象的相等性,如果两个对象不同的话,那么返回 false。 HashMap 比较快,因为是使用唯一的键来获取对象,HashSet 较 HashMap 来说比较慢。 4.1.3 HashMap 与 TreeMap
10 2
|
18天前
|
存储 Java 索引
JavaSE——集合框架一(5/7)-Set系列集合:Set集合的特点、底层原理、哈希表、去重复原理
JavaSE——集合框架一(5/7)-Set系列集合:Set集合的特点、底层原理、哈希表、去重复原理
29 1
|
1月前
|
C++ 容器
【C++】红黑树模拟实现STL中的map与set
【C++】红黑树模拟实现STL中的map与set
|
1月前
|
算法 测试技术 C++
【C++】map&set的底层结构 -- AVL树(高度平衡二叉搜索树)(下)
【C++】map&set的底层结构 -- AVL树(高度平衡二叉搜索树)(下)
|
1月前
|
C++ 容器
【C++】map&set的底层结构 -- AVL树(高度平衡二叉搜索树)(上)
【C++】map&set的底层结构 -- AVL树(高度平衡二叉搜索树)(上)
|
4天前
|
存储 算法 NoSQL
C++一分钟之-map与set容器详解
【6月更文挑战第21天】C++ STL的`map`和`set`是基于红黑树的关联容器,提供有序存储和高效查找。`map`存储键值对,键唯一,值可重复;`set`仅存储唯一键。两者操作时间复杂度为O(log n)。常见问题包括键的唯一性和迭代器稳定性。自定义比较函数可用于定制排序规则,内存管理需注意适时释放。理解和善用这些工具能提升代码效率。
10 3
|
6天前
|
存储 编译器 C++
|
27天前
|
C语言
从C语言到C++_29(红黑树封装set和map)红黑树迭代器的实现(下)
从C语言到C++_29(红黑树封装set和map)红黑树迭代器的实现
27 3