List集合排序

1、集合工具类(包装类)Collections.sort

使用Collections提供的sort方法,对集合进行排序

Collections.sort(list);

实现原理:
将list转成了数组对象后,调用了Array的sort方法,将数组排序,再用list的迭代器(注意不是collection迭代器)一个个得赋值回去,就使得传入的list变成了一个有序的list

  • 由于set,map都有SortedSet,TreeSet和SortedMap实现类,所以Collections中并没有对set和map支持sort方法
  • sort方法默认的顺序是升序,如果你想要降序排,你可以调用Collections中的另一个sort方法
public class SortListDemo {public static void main(String[] args) {List<Integer> list = new ArrayList<>();Random random = new Random();//随机生成一个数,作为list元素for(int i=0;i<10;i++){//向末尾添加随机的数list.add(random.nextInt(100));}System.out.println(list);//使用Collections提供的sort方法,对集合进行排序Collections.sort(list);System.out.println(list);}
}

Collection 与 Collections 的区别

1. java.util.Collection 是一个集合接口

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

2. java.util.Collections 是一个包装类

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

2、自定义排序

1. 比较器

Comparable接口:

Collections的sort方法是对集合元素进行自然排序
在使用Collections的sort排序的集合元素都必须是Comparable接口的实现类
该接口表示其子类是可比较的,因为实现该接口必须重写抽象方法 int compareTo(T t);

这个接口用于给需要排序的类来实现的,一旦实现,这个类就会按这个方式排序
比如说我们常见的String类就实现了这个接口,并重写了里面的compareTo
所以我们对字符串可以利用compareTo方法进行排序

Comparator接口(一般用这种):

一旦Java类实现了Comparable接口,其比较逻辑就已经确定(只能按写在自定义类中的算法排序)
如果希望在排序的操作中临时指定比较规则,可以采用Comparator接口回调的方式。
Comparator接口要求实现类必须重写其定义的方法 int compare(T o1,T o2)

通过比较器比较自定义类

自定义排序必须提供比较器
比较器为一个自定义的实现了比较器的类的实例化对象

自定义排序语法
Collections.sort(list,比较器);

2.实现方式

① 自定义一个比较器类,实现比较器的接口(Comparator 尖括号里面传入比较器比较的类)

注意:必须重写compare方法,返回值为int

然后使用Collections.sort时,在括号里传入需要排序的列表和new一个自定义比较器类的实例对象

Collections.sort(list, new ByAge());

② 匿名内部类(上班后常用,记得简写),实现原理同上

        //使用匿名内部类排序Comparator<Person> byAge = new Comparator<Person>(){@Overridepublic int compare(Person o1, Person o2) {return o1.age-o2.age;}};//按照匿名内部类比较器规则进行年龄排序//这里只需要把刚才的内部类对象传递进来就行了Collections.sort(list,byAge);System.out.println(list);//上班后上述匿名内部类代码可以简化为Collections.sort(list,new Comparator<Person>(){public int compare(Person o1, Person o2){return o1.age-o2.age;}});System.out.println(list);//匿名内部类实现,按名字顺序比较Collections.sort(list,new Comparator<Person>(){public int compare(Person o1, Person o2) {//compareTo 按字典顺序比较两个字符串(字符编码)return o1.name.compareTo(o2.name);}});System.out.println(list);

3、自定义排序代码

package collection.comparator;import java.text.Collator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;/*** 自定义排序(通过比较器比较自定义类)* @author Tian**/
public class SortListDemo {public static void main(String[] args) {/** 对一组人进行自定义排序*/List<Person> list = new ArrayList<>();list.add(new Person("徐凤年",23,130));list.add(new Person("姜泥",20,96));list.add(new Person("裴南苇",32,98));list.add(new Person("洛阳",800,100));/** 自定义排序必须提供比较器* 比较器为一个自定义的实现了比较器的类的实例化对象*///Collections.sort(list,比较器);//按照自定义比较器规则进行年龄排序Collections.sort(list, new ByAge());System.out.println(list);//按照自定义比较器规则进行体重排序Collections.sort(list, new ByWeight());System.out.println(list);//使用匿名内部类排序Comparator<Person> byAge = new Comparator<Person>(){@Overridepublic int compare(Person o1, Person o2) {return o1.age-o2.age;}};//按照匿名内部类比较器规则进行年龄排序//这里只需要把刚才的内部类对象传递进来就行了Collections.sort(list,byAge);System.out.println(list);//上班后上述匿名内部类代码可以简化为Collections.sort(list,new Comparator<Person>(){public int compare(Person o1, Person o2){return o1.age-o2.age;}});System.out.println(list);//匿名内部类实现,按名字顺序比较Collections.sort(list,new Comparator<Person>(){public int compare(Person o1, Person o2) {//compareTo 按字典顺序比较两个字符串(字符编码)//详情见拓展return o1.name.compareTo(o2.name);}});System.out.println(list);//按名字拼音的首字母排序//创建了一个字符串的列表,用来接收人类中的姓名List<String> str = new ArrayList<>();//循环遍历人类列表,将姓名放到字符串列表中for(Person p : list){str.add(p.name);}//使用比较器对名字列表进行排序/** Collator.getInstance(java.util.Locale.CHINA)* 这个方法是* Collator类调用了一下他的工厂方法(静态方法的一种常见用途)* 该方法会返回一个比较器的对象,内部实现了按字符串首字符的拼音首字母排序* 这个方法需要传入一个参数,语言包,我们这里传入的是中文*/Collections.sort(str,Collator.getInstance(java.util.Locale.CHINA));//输出排序后的字符串列表System.out.println(str);//问题:只能修改String列表,怎么把这个修改顺序的影响扩大到Person列表中呢}
}/*** 根据年龄比较两人的比较器* 自定义比较器,实现比较器的接口* Comparator<Person>* 尖括号里面传入比较器比较的类*/
class ByAge implements Comparator<Person>{/*** 重写接口里面的比较方法* 注意:该方法返回值需要有三个状态(0、正数、负数)*/@Overridepublic int compare(Person o1, Person o2) {//按照两个人的年龄比较
//      if(o1.age == o2.age){//          return 0; //返回0,表示人类o1与o2年龄一样
//      }else if(o1.age > o2.age){//          return 1; //返回正数,表示01大于o2年龄
//      }else{//          return -1; //返回负数,表示o1年龄小于o2年龄
//      }//可以优化为return o1.age-o2.age;//倒叙可以写为//return -(o1.age-o2.age);}
}/*** 根据体重排序的比较器*/
class ByWeight implements Comparator<Person>{/*** 比较体重的比较器* 体重是double类型,强转可能精度缺失(-0.5会变为0)* 所以使用Math.signum用来取差的符号* static double    signum(double d)* 如果参数为零,则为零;如果参数大于零则为1.0;如果参数小于零,则为-1.0* 获取符号后,我们可以进行强转,不会影响精度了*/@Overridepublic int compare(Person o1, Person o2) {return (int) Math.signum(o1.weight-o2.weight);}
}/*** 自定义类:人类(供测试用)* @author Tian**/
class Person{String name;int age;double weight;public Person(String name, int age, double weight) {this.name = name;this.age = age;this.weight = weight;}@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + ", weight=" + weight + "]";}}

4、拓展

1. 字符串大小比较问题

字符串提供比较大小的方法
int compareTo(String anotherString)
按字典顺序比较两个字符串(按照字符编码进行比较)

比较两个字符串时:
先比较前两个字符大小(第一个汉字),如果可以比较出来就返回,不行的话就比较第二个
返回0,表示相等;返回正数表示第一个字符串大;返回负数,表示第一个字符串小

先比较前两个字符大小(第一个汉字),如果可以比较出来就返回,不行的话就比较第二个

public static void main(String[] args) {String s1 = "徐凤年";String s2 = "邓太阿";String s3 = "曹长卿";int n = s1.compareTo(s2);System.out.println(n);}

2. 按字符串首字符的拼音首字母排序

使用比较器对名字列表进行排序
Collator.getInstance(java.util.Locale.CHINA)
这个方法是
Collator类调用了一下他的工厂方法(静态方法的一种常见用途)
该方法会返回一个比较器的对象,内部实现了按字符串首字符的拼音首字母排序
这个方法需要传入一个参数,语言包,我们这里传入的是中文

        //按名字拼音的首字母排序//创建了一个字符串的列表,用来接收人类中的姓名List<String> str = new ArrayList<>();//循环遍历人类列表,将姓名放到字符串列表中for(Person p : list){str.add(p.name);}//使用比较器对名字列表进行排序/** Collator.getInstance(java.util.Locale.CHINA)* 这个方法是* Collator类调用了一下他的工厂方法(静态方法的一种常见用途)* 该方法会返回一个比较器的对象,内部实现了按字符串首字符的拼音首字母排序* 这个方法需要传入一个参数,语言包,我们这里传入的是中文*/Collections.sort(str,Collator.getInstance(java.util.Locale.CHINA));//输出排序后的字符串列表System.out.println(str);//问题:只能修改String列表,怎么把这个修改顺序的影响扩大到Person列表中呢

ps.工厂方法

静态方法的一种常见用途,用于构造对象

工厂方法的返回值为一个类的对象,用于使用一个类的静态方法完成创建一个我们需要的对象

比如上面的Collator.getInstance() 就是Collator中的静态方法,用来创建一个比较器对象

List集合排序、自定义比较器排序相关推荐

  1. TreeSet集合(自然排序和比较器排序)

    TreeSet集合 自然排序和比较器排序 ​ 当指执行插入排序.希尔排序.归并排序等算法时,比较两个对象"大小"的比较操作.我们很容易理解整型的 i>j 这样的比较方式,但当 ...

  2. TreeSet-自然排序与比较器排序

    TreeSet-自然排序与比较器排序 特性 TreeSet是有序的(即按照一定的规则排序),是用二叉树实现的. TreeSet 的存取顺序无序 自然排序 可以通过comparable接口重写compa ...

  3. java中自然排序和比较器排序

    这里所说到的Java中的排序并不是指插入排序.希尔排序.归并排序等具体的排序算法.而是指执行这些排序算法时,比较两个对象"大小"的比较操作.我们很容易理解整型的 i>j 这样 ...

  4. android自定义比较器,java – 使用自定义比较器排序的集合不起作用

    我创建了一个自定义Comparator来对字符串的ArrayList进行排序.我已通过调试器运行它并观察它正确比较和返回值.但是,我的数组没有排序.因为我不熟悉 Java& Android,可 ...

  5. java中的排序方法,Java中的排序比较方式:自然排序和比较器排序

    这里所说到的Java中的排序并不是指插入排序.希尔排序.归并排序等具体的排序算法.而是指执行这些排序算法时,比较两个对象"大小"的比较操作.我们很容易理解整型的 i>j 这样 ...

  6. Java基础知识 21(Set集合,HashSet集合以及它的三种遍历方式(迭代器,增强for循环,forEach),LinkedHashSet集合,TreeSet集合(自然排序法,比较器排序法))

    Java基础知识 21 Set集合 Set集合:一个不包含重复元素的Collection集合,元素不重复,List集合是允许元素重复的. Set接口的三个字类:HashSet(),LinkedHash ...

  7. 集合到文件数据排序改进版

    案例需求 键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩).要求按照成绩总分从高到低写入文本文件 格式:姓名,语文成绩,数学成绩,英语成绩 举例:林青霞,98,99,100 分析步骤 定义学 ...

  8. 关于自然排序Comparable 和 比较器排序Comparator

    简要区别 自然排序可用在list和set中,当用在list集合中时要通过Collections(list)对排序规则进行调用,谁是最后一个排序的就按照哪个排序规则进行排序 当用在TreeSet集合中时 ...

  9. IO流案例,集合到文件数据排序、复制单级和多级文件夹及复制文件的异常处理

    目录 一.集合到文件数据排序 二.复制单级文件夹 三.复制多级文件夹 四.复制文件的异常处理 基本做法: JDK7版本改进: JDK9版本改进: 一.集合到文件数据排序 需求: 键盘录入5个学生信息( ...

  10. ElasticSearch painless脚本实现自定义打分排序

    背景: 遇到了这样一个需求,对于历史购买的商品优先排序 自定义打分排序规则 自定义打分规则,其实就是可以根据打分规则进行排序.注意:只能对索引的keyword属性进行排序,TEXT类型的要加.keyW ...

最新文章

  1. 用mpvue实现的微信小程序版cnode社区
  2. 有效前沿—让你的投资收益最大化
  3. SSM框架搭建(四) springmvc和mybatis的配置
  4. C memset 踩坑
  5. STL中的map集合扩展字段比较方便
  6. c语言 方程改main的值_c语言main函数里的参数argv和argc解析
  7. 希捷四十载:如何做好一家非常规存储公司?
  8. Bootstrap文件上传插件File Input的使用
  9. 2019 牛客多校第三场 H Magic Line
  10. linux常用命令_linux常用命令
  11. CenterCrop的Video View
  12. 日系清新LR调色预设支持PS/PR/FCPX/达芬奇/AE/LUT图片滤镜
  13. java xml转换xsd,将java类转换成xsd文件
  14. LordPE v1.4 by yoda
  15. 为什么要选择Linux
  16. 《Spring实战》读书笔记-第1章 Spring之旅
  17. word中如何删除某一页上的页眉
  18. 10月20日前!武汉市科技成果转化中试平台(基地)备案申报条件及流程梳理
  19. mac怎么修改hosts文件
  20. C++ 并发指南<future>(2)std::packaged_task

热门文章

  1. 随机信号分析第2版 [赵淑清郑薇编著] (部分)课后作业答案(自己写的)
  2. 应对 勒索病毒 补丁、免疫工具、关闭445端口
  3. CSRF和SSRF漏洞
  4. C# 把文件和文件夹 放到回收站 (出现Unknown err (0x402) 无法删除 文件:无法读取源文件或磁盘 解决)
  5. 【Python】实现商品信息管理系统(界面版,附带数据库)
  6. e580显卡驱动_联想e580网卡驱动下载|联想e580无线网卡驱动官方版_ - 极光下载站...
  7. p12解析流程_解析P12证书 | 学步园
  8. python打包生成so文件
  9. javashop源码百度云,java电商系统源码分享,Javashop多用户商城源码
  10. 一元线性回归(最小二乘法)