Java中TreeSet、HashSet、Collection重写比较器

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

一、什么是比较器?

比较器是一种可以对集合或数组中的元素按照自定义的方式进行排序的对象,它是实现了Comparator接口的类的实例,可以决定元素在集合或映射中如何被排序和存储。

比较器有两种基本类型:自然排序和定制排序。自然排序是指让要排序的类实现Comparable接口,并重写compareTo方法,来定义元素的默认排序方式。定制排序是指创建一个实现了Comparator接口的类,并重写compare方法,来定义元素的特定排序方式。定制排序可以覆盖自然排序,也可以在自然排序不适用的情况下使用。

二、TreeSet为什么重写比较器?

TreeSet是一个有序的集合,它可以按照自然排序或者定制排序来排列元素。自然排序是指让要排序的类实现Comparable接口,并重写compareTo方法,来定义元素的默认排序方式。定制排序是指创建一个实现了Comparator接口的类,并重写compare方法,来定义元素的特定排序方式。

TreeSet实现了Set接口,可以去重内容相同的元素。比如存入Integer类型的两个数据,6和6,遍历输出,只会输出一个6。但是对于自定义类,添加进TreeSet排序,会报错,因为比较器无法比较一个类。因此我们重写比较器,按照类中的指定属性进行排序


代码展示:

直接使用这个模板也是可以的,根据什么排序,就使用什么来做减法。等于0时会去重,正数会从小到大排序,负数会从大到小排序。

// 创建一个按照年龄升序排列的TreeSet
TreeSet<Person> ts = new TreeSet<>(new Comparator<Person>() {
    @Override
    public int compare(Person p1, Person p2) {
        return p1.getAge() - p2.getAge();
    }
});

三、HashSet为什么重写比较器?

HashSet是一个无序的集合,它不保证元素的排列顺序,并且不允许重复元素。HashSet是基于哈希表实现的,它通过调用元素的hashCode和equals方法来判断元素是否相等和决定元素在哈希表中的位置。

当我们添加进HashSet中相同属性的两个类,想去重时,可以选择重写hashcode方法和equal方法。(HashSet的比较器底层实现通过hashcode和equal,两个返回值都为true时,才会去重)

代码展示:

// 定义一个Person类,并重写hashCode和equals方法
class Person {
    private String name;
    private int age;

    // 省略构造方法和get/set方法

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Person person = (Person) obj;
        return age == person.age && Objects.equals(name, person.name);
    }
}

// 创建一个HashSet对象,并添加Person对象
HashSet<Person> hs = new HashSet<>();
hs.add(new Person("张三", 20));
hs.add(new Person("李四", 21));
hs.add(new Person("张三", 20)); // 这个对象不会被添加,因为和第一个对象相等

四、Collection为什么重写比较器?

Collection是一个接口,它是Java集合框架的根接口,它定义了一些通用的操作方法,如添加、删除、遍历、排序等。Collection接口有很多实现类,如ArrayList、LinkedList、HashSet、TreeSet等。Collection接口本身并不需要重写比较器,但是它提供了一个sort方法,可以对实现了List接口的集合进行排序。该方法有两个重载形式,一个是使用自然排序,另一个是使用定制排序。

当我们想对ArryList集合进行排序时(ArryList本身无法排序,没有比较器),可以通过重写比较器来进行排序。

// 创建一个ArrayList对象,并添加一些字符串
ArrayList<String> al = new ArrayList<>();
al.add("apple");
al.add("banana");
al.add("orange");
al.add("pear");

// 使用自然排序对ArrayList进行排序
Collections.sort(al);

// 使用定制排序对ArrayList进行排序,按照字符串长度升序排列
Collections.sort(al, (s1, s2) -> s1.length() - s2.length());

这里是希望和大家一起进步的小高,愿意和读者们热情探讨😊

17.集合Set,HashSet,TreeSet及其底层实现HashMap和红黑树;Collection总结 ONE.Set集合 one.Set集合的特点 无序,唯一 TWO.HashSet集合 1.底层数据结构是哈希表(是一个元素为链表的数组) 2.那么HashSet如何来实现元素的唯一性的呢? 通过一HashSet添加字符串的案例查看HashSet中add()的源码,看为什么相同的字符串没有被加入HashSet中 interface Collection { ... } int... 阅读详情

相关推荐

TreeSet、TreeMap、HashSet、HashMap底层实现

TreeMap底层基于红黑树,以下是源代码,先指定一个根节点,若该根节点不存在,则说明TreeMap里面没有元素,将当前准备加入的元素(Entry)加入进去当成根节点。 如果里面已经 存在元素,再判断是否TreeMap是否含有比较器,如果比较器不为空,就按照比较器的比较方法进行比较,如果为空,按照该(key)自己的内部的自然顺序进行 比较,前提是该key是有比较性的,否则,需要将该类继承com

学习笔记 3053

Java重写比较器java.util.Comparator的注意事项

版权声明:本文为博主原创文章,转载请注明出处:https://twocups.cn/index.php/2020/02/05/18/ 有时我们需要对同一类型的对象进行多种不同方式的排序,而自然排序 Comparable 并不能实现。这里我们就需要重写比较器,可以让对象数组或集合以自定义的排序规则进行排序。 示例 给定一组非负整数,重新排列它们的顺序使之组成一个最大的整数。例如 [10, 2] 的输出为210,[3, 30, 34, 5, 9] 的输出为9534330。 这道题解法的关键就是排序,具体的规则.

Arthur_Holmes的博客 3559

重写比较器

1.对于优先队列,经常用于构建小顶堆。2.对于arraylist。

weixin_41636858的博客 252

Java 基本类型比较 + 自定义类比较 + 对象的三种比较方法重写equals方法 /重写compareTo方法 /使用比较器

本篇主要讲解实现自定义类的比较,使自定义的类也存在优先级之分

The_emperoor_man的博客 2776

java实现Comparable接口或者重写Comparator(比较器)方法

目录1.前言2.实现Comparable接口3.重写Comparator(比较器)方法4.总结5.参考文献 1.前言 由下面的继承结构图可以看出来,TreeSet继承了SortedSet的特性,而SortedSet接口又定义了一个comparator抽象方法,返回一个Comparator,这意味着TreeSet的底层是可以自动进行排序的。 但是java中只对Integer和String类型的数据结构重写了Comparator方法,如果我们想要自定义一个数据结构,那么如何让TreeSet实现我们想实现的排序方

Zeeland的博客 5410

LeetCode 每日一题 2020-11-6(根据数字二进制下 1 的数目排序 sort 函数)

1356. 根据数字二进制下 1 的数目排序 难度简单 给你一个整数数组arr。请你将数组中的元素按照其二进制表示中数字1的数目升序排序。 如果存在多个数字二进制中1的数目相同,则必须将它们按照数值大小升序排列。 请你返回排序后的数组。 思路一: 对原数组排序,统计数组中各数字的二进制中包含 1 的个数,保存到map中并以此进行排序。 vector<int>sortByBits(vector<int>&arr){ un...

Baimax的博客 392

Java---Collection单列集合详解

对于Java中关于单列集合的基本知识,单列集合简单点来说就是Java中储存数据的容器,增删改查都很方便,不需要自己去想,本文就是对该知识点的基本讲解

gaoqiandr的博客 1177

Collection集合、LinkedList集合

Collection集合 Collection集合的使用步骤: 创建集合对象 Collection<String> c = new ArrayList<>(); 添加元素 c.add("hello"); c.add("world"); c.add("java"); 遍历集合 3.1:通过集合对象获取迭代器对象 Iterator<String> it = c.iterator(); 3.2:通过迭代器对象的hasNext()方法判断是否还有元素 3.3:

qq_56659700的博客 271

Collection接口下的Set、List

Collection接口下的Set集合Collection接口介绍Collection接口的常用方法Set集合HashSetTreeSet Collection接口 介绍 Collection接口是List接口和Set接口的父接口,通常情况不会直接使用,Collection接口中定义了一些通用的方法,通过他们可以实现对集合的添加、删除、等基本操作。List接口和Set接口实现了Collection接口,所有这些方法对List和Set集合是通用的。 Collection接口的常用方法 add(E ob

weixin_43347737的博客 635

第六单元【Java集合框架】List、Set、Map、泛型、比较器 最全总结

HashMap:线程不安全,key、value均可为null,底层数组+链表+红黑树,读写效率最高,日常开发首选。Hashtable:线程安全,key、value禁止为null,全量加锁,性能极差,已过时。TreeMap:线程不安全,key禁止为null,底层红黑树,可根据key自动排序。- 使用方式:实现接口,重写compareTo方法,对比当前对象与传入对象。- 去重规则:compareTo方法返回0时,判定元素重复,无法存入集合。- 常用泛型标识:T(任意类型)、K(键)、V(值)、E(集合元素)。

2601_95470346的博客 328

关于Collection集合

Collection集合 Coeclltion集合为一个接口,List和Set接口继承了该Coeclltion。 List有实现类ArrayList、LinkedList和Vector。Set有实现类HashSet和接口SortedSet,TreeSet类实现了接口SortedSet。 集合只能存储引用类型,如果在集合中add基础类型时会自动装箱。 关系图为下: List接口:有序、有下标、元素可重复。 Set接口:无序、无下标、元素不能重复。 标题Collection集合中的遍历: 1、使用增强fo

m0_61265922的博客 147

集合

集合Collection集合概述继承体系collection注意事项迭代器ListArrayListLinkedListSetThreeSet比较器的实现 Collection 集合概述 集合体系共分为两大类,分别是List和Set,并且都继承了CollectionCollection集合由于底层是Object[]数组,所以只能存储单个元素,并且只能保存引用数据类型,不能保存基本数据类型。存储基本数据类型可以使用基本数据类型对应的包装类,完成自动装箱操作 常用方法: boolean add() : 添

changlinke的博客 151

集合核心知识

集合框架: 1张图: Collection(无序 可重复) Map(存储K-V) | | | | List Set HashMap TreeMap (有序、可重复) (无序 唯一) /

纯洁滴小熊的博客 156

1246四个数字讲清集合框架!!!简单易懂且全面

1张图 Collection(无序 可重复) Map(存储K-V) | | | | List Set ...

weixin_45641900的博客 226

java中的Set系列集合:HashSet、LinkedHashSetTreeSet

●无序(不代表乱序)●不可重复(不能存储重复元素),●没有索引,不能用普通的for进行遍历,但是能用迭代器或者增强for循环进行遍历● 底层采用数组+链表+红黑树的结构形式来存储数据,其实就是用HashMap的key键来存储数据,在创建HashSet对象的时候就会创建一个HashMap来存储数据(如下图),所以其采用HashMap存储数● 扩容机制:① 当底层数组长度大于等于阈值的时候② 当链表长度大于等于8的时候,并且数组长度小于64。

weixin_65378964的博客 1107

collection之set集合的使用:HashSet、LinkedHashSetTreeSet使用案例

Set集合概述及特点 A:Set集合概述及特点: 通过API查看即可 B: 案例演示: 无序(存储和取出的顺序)和唯一 案例一: import java.util.Collection; import java.util.HashSet; public class SetDemo { public static void main(String[] args) { //...

yalu_123456的博客 440

java TreeSet(Map)/确认集合选型/Collection工具类

在不做处理/使用无参构造器的时候,按理来说输出应该是无序的,但我试验了一下还是有序的,可能是我用的是jdk21会自动加上。进入了在空集中添加元素的addEntryToEmptyMap,直接计入root中了(可以看到用的还是map的源码)由于t,也就是root不为空,所以把comparator(比较器)赋给cpr,cpr就是我们的匿名内部类。不过对应的,由于前面所说的重复的不会加进去,所以若是add长度一样的字符串,是加入不进去的。由于我们是有构造器的,所以自然进入了cpr不为空的语句。

2301_81088399的博客 914

Java基础之HashSetTreeSet

无序:元素存入和取出的顺序无法保证一致性 不重复:重复的元素不会被存入 无索引:集合中没有索引,无法通过索引操作元素 (因为无索引,只能是迭代器,增强for遍历)

weixin_47543906的博客 951

JAVA集合03_HashSet、LinkedHashSet概述、TreeSet自然顺序、比较器顺序

HashSet、LinkedHashSet概述、TreeSet自然顺序、比较器顺序

所得皆惊喜 541
上一篇: Matlab实现Kmeans算法(每行代码标注详细注解)
下一篇: Mysql中的常见SQL语句——表格版
Gavana.
Gavana. 新星创作者: Java技术领域 新星创作者: Java技术领域
博客等级 码龄6年 1万+粉丝 104原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gavana.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值