【JAVA】关于集合元素排序

⭐️Java集合的回顾(集合的排序)

image-20220320100249565

1️⃣Set

Set集合特点

  • 不包含重复元素的集合

  • 没有带索引的方法,所以不能使用普通for循环遍历

TreeSet

特点
  • 元素有序:这里的有序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体的排序取决于构造方法

    • TreeSet():根据元素的自然排序进行排序(数字从小到大)

    • TrssSet(Comparator comparator):根据指定的比较器进行排序

  • 包含set集合的特点

元素有序且不重复
public class AboutSet { public static void main(String[] args) { //创建set集合 Set set = new TreeSet(); set.add(1); set.add(1); set.add(5); set.add(3); for(Object o:set) { System.out.println(o); } } } output:1 3 5
比较器排序
🚀从小到大排序-分析比较过程

起始情况下:s1和s2都被赋值为集合添加的第一个值,也就是5 5

第二次添加:s1(新元素),s2(已经添加的元素),s1-s2<0,s1的位置和s2的位置不进行交换 2 5

第三次添加:s1和第一次添加的元素比较,s1-s2<0,不交换,再和第二次添加的元素比较,s1-s2==0不添加 2 5

第四次添加:1-5<0 不交换,1-2<0不交换,1 2 5

(规律)第五次添加:3-5<0 不交换,3-2>0交换(由于已经有序,2大于1,3和2交换,2前面的就不用再比较了),1 2 3 5

(事实上):3-2>0放到2的后面,3-5<0放5的前面

(按规律) 第六次添加:8-5>0 放5后面,结束 1 2 3 5 8

(事实上):8-2>0放2后面,8-5>0放5后面 结束 1 2 3 5 8

❗️注意
  • 上面是模拟运行的过程,这是通过debug分析执行过程的出的过程,但是第五次和第六次添加的时候却出现了和前几次不同的情况,这一点我还在困惑中,不过我感觉可能和在元素在空间中存放的位置(地址有关)。至于为什么说是前几次形成的规律,是为了便于自己记忆比较的过程。

  • 比较过程的描述用交换我觉得可能不太准确,因为在比较的过程中,并不能确定s1添加进去和s2比较的相对位置,所以按照从小到大(从左到右)的描述,我觉得用放前面放后面相对准确一些,也就是s1-s2>0放到s2的后面;s1-s2<0就放在s2的前面(s1-s2==0也放前面)望周知

public class AboutSet { public static void main(String[] args) { //创建set集合 //通过比较器排序Comparator自定义排序方式 Set<Integer> set = new TreeSet<>(new Comparator<Integer>() { @Override public int compare(Integer s1, Integer s2) { return s1-s2; } }); set.add(5); set.add(2); set.add(2); set.add(1); set.add(3); set.add(8); for(Object o:set) { System.out.println(o); } } }
贴上运行完的截图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NU2O8IxG-1647748210974)(D:\资源\学习工作\lnnau\typora笔记\笔记图片\image-20220320111034431.png)]

🤖从大到小排序

起始:s2和s1都被赋值为第一个被添加的值5 5

第二次添加:s2(已经添加过的元素)-s1(新元素)>0,2放5的后面 5 2

第三次添加:5-2>0,放5后面,2-2==0,不添加 5 2

第四次添加:5-1>0,放5后面,2-1>0放2后面 5 2 1

第五次添加:2-3<0,放2前面,5-3>0放5后面 5 3 2 1

第六次添加:2-8<0,放2前面,5-8<0放5前面 8 5 3 2 1

需要注意的和从小到大类似,不再赘述

public class AboutSet { public static void main(String[] args) { //创建set集合 //通过比较器排序Comparator自定义排序方式 Set<Integer> set = new TreeSet<>(new Comparator<Integer>() { @Override public int compare(Integer s1, Integer s2) { return s2-s1; } }); set.add(5); set.add(2); set.add(2); set.add(1); set.add(3); set.add(8); for(Object o:set) { System.out.println(o); } } }
🔚总结

匿名类的方式

s1:新添加元素 s2:已经添加过的元素

实现接口的方式

this. 新添加的元素 s:已经添加的元素

从小到大排序

格式:s1-s2

s1-s2=num num>0 s1放在s2的后面

​ num<0 s1放在s2的前面

​ num==0 s1不添加

从大到小排序

s2-s1=num num>0 s1放在s2的后面

​ num<0 s1放在s2的前面

​ num==0 s1不添加

s1在前降序排列,s1在后升序排列

处理多重条件排序

package com.reback; import java.util.*; /** * @Author Lunau * @Create 2022-03-20 10:00 * @Description 对set集合及其实现类探究 * @Result 杜甫 2013 21 李贺 2014 25 李白 2014 20 王维 2015 22 */ public class AboutSet { public static void main(String[] args) { //创建set集合 //通过比较器排序Comparator自定义排序方式 Set<Student> set = new TreeSet<Student>(new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { //按照id从小到大,age从大到小排序 int num1 = s1.id-s2.id; int num2 = num1==0?s2.age-s1.age:num1; return num2; } }); //添加元素 set.add(new Student(2014,20,"李白")); set.add(new Student(2013,21,"杜甫")); set.add(new Student(2015,22,"王维")); set.add(new Student(2014,25,"李贺")); for(Student s:set) { System.out.println(s.name+" "+s.id+" "+s.age); } } } class Student{ int id; int age; String name; public Student(int id, int age, String name) { this.id = id; this.age = age; this.name = name; } }

2️⃣List

2.1 List集合子类特点

ArrayList:底层数据结构是数组,查询快,增删慢

LinkedList:底层数据结构是链表,查询慢,增删快

2.2 List集合排序方法

以ArrayList实现类为例

由于比较器排序的过程和Set集合排序的方法相同,但是需要知道的是,Set集合的排序可以直接在创建Set集合的时候进行比较器排序(通过创建比较器new Comparator),而List列表需要用Collections里的sort方法进行排序

⭐️但是排序比较器的构造是一致的,只是排序的方法不一样

package com.reback; import java.util.Collections; import java.util.Comparator; import java.util.LinkedList; import java.util.List; /** * @Author Lunau * @Create 2022-03-20 12:57 * @Description 关于list排序探究 * @Result */ public class AboutList { public static void main(String[] args) { //创建list集合对象 以LikeList为例 List<Student> list = new LinkedList<>(); //添加元素到集合 list.add(new Student(2014,20,"李白")); list.add(new Student(2013,21,"杜甫")); list.add(new Student(2015,22,"王维")); list.add(new Student(2014,25,"李贺")); //采用 Collections.sort(list, new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { //按照id从小到大,age从大到小排序 int num1 = s1.id-s2.id; int num2 = num1==0?s2.age-s1.age:num1; return num2; } }); //打印集合 for(Student s:list) { System.out.println(s.name+" "+s.id+" "+s.age); } } }

3️⃣ 容易混淆的

Collection和Collections的区别

Collection:是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供最大化的统一操作方式。

Collections:是一个包装类。它包含各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。

简单理解:Collection是定义集合的,实现集合;Collections是管理集合,用来对集合进行操作的,比如排序、反转等操作。

Comparator比较器

该比较器中提供了许多方法,需要终点记忆的是compara()方法,在自定义排序规则的时候就要用对该方法进行重写,

重写的规则前面已经探讨过了。

👉总结

写这篇总结的起因是在写蓝桥杯真题利用List列表排序时,发现过去学习的知识忘记了好多,之前一直用的Set的比较器排序(comparator)比较多,突然让用列表进行比较器排序,发现和自己想的并不是那么一回事,列表排序的方法和set有些不同,查阅一些其他人的博客,加上自己的一些debug,总结出一点能用的知识。


__EOF__

本文作者lnnau
本文链接https://www.cnblogs.com/wlunan/p/18538048.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Lnnau  阅读(24)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示