List集合排序、自定义比较器排序
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集合排序、自定义比较器排序相关推荐
- TreeSet集合(自然排序和比较器排序)
TreeSet集合 自然排序和比较器排序 当指执行插入排序.希尔排序.归并排序等算法时,比较两个对象"大小"的比较操作.我们很容易理解整型的 i>j 这样的比较方式,但当 ...
- TreeSet-自然排序与比较器排序
TreeSet-自然排序与比较器排序 特性 TreeSet是有序的(即按照一定的规则排序),是用二叉树实现的. TreeSet 的存取顺序无序 自然排序 可以通过comparable接口重写compa ...
- java中自然排序和比较器排序
这里所说到的Java中的排序并不是指插入排序.希尔排序.归并排序等具体的排序算法.而是指执行这些排序算法时,比较两个对象"大小"的比较操作.我们很容易理解整型的 i>j 这样 ...
- android自定义比较器,java – 使用自定义比较器排序的集合不起作用
我创建了一个自定义Comparator来对字符串的ArrayList进行排序.我已通过调试器运行它并观察它正确比较和返回值.但是,我的数组没有排序.因为我不熟悉 Java& Android,可 ...
- java中的排序方法,Java中的排序比较方式:自然排序和比较器排序
这里所说到的Java中的排序并不是指插入排序.希尔排序.归并排序等具体的排序算法.而是指执行这些排序算法时,比较两个对象"大小"的比较操作.我们很容易理解整型的 i>j 这样 ...
- Java基础知识 21(Set集合,HashSet集合以及它的三种遍历方式(迭代器,增强for循环,forEach),LinkedHashSet集合,TreeSet集合(自然排序法,比较器排序法))
Java基础知识 21 Set集合 Set集合:一个不包含重复元素的Collection集合,元素不重复,List集合是允许元素重复的. Set接口的三个字类:HashSet(),LinkedHash ...
- 集合到文件数据排序改进版
案例需求 键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩).要求按照成绩总分从高到低写入文本文件 格式:姓名,语文成绩,数学成绩,英语成绩 举例:林青霞,98,99,100 分析步骤 定义学 ...
- 关于自然排序Comparable 和 比较器排序Comparator
简要区别 自然排序可用在list和set中,当用在list集合中时要通过Collections(list)对排序规则进行调用,谁是最后一个排序的就按照哪个排序规则进行排序 当用在TreeSet集合中时 ...
- IO流案例,集合到文件数据排序、复制单级和多级文件夹及复制文件的异常处理
目录 一.集合到文件数据排序 二.复制单级文件夹 三.复制多级文件夹 四.复制文件的异常处理 基本做法: JDK7版本改进: JDK9版本改进: 一.集合到文件数据排序 需求: 键盘录入5个学生信息( ...
- ElasticSearch painless脚本实现自定义打分排序
背景: 遇到了这样一个需求,对于历史购买的商品优先排序 自定义打分排序规则 自定义打分规则,其实就是可以根据打分规则进行排序.注意:只能对索引的keyword属性进行排序,TEXT类型的要加.keyW ...
最新文章
- 用mpvue实现的微信小程序版cnode社区
- 有效前沿—让你的投资收益最大化
- SSM框架搭建(四) springmvc和mybatis的配置
- C memset 踩坑
- STL中的map集合扩展字段比较方便
- c语言 方程改main的值_c语言main函数里的参数argv和argc解析
- 希捷四十载:如何做好一家非常规存储公司?
- Bootstrap文件上传插件File Input的使用
- 2019 牛客多校第三场 H Magic Line
- linux常用命令_linux常用命令
- CenterCrop的Video View
- 日系清新LR调色预设支持PS/PR/FCPX/达芬奇/AE/LUT图片滤镜
- java xml转换xsd,将java类转换成xsd文件
- LordPE v1.4 by yoda
- 为什么要选择Linux
- 《Spring实战》读书笔记-第1章 Spring之旅
- word中如何删除某一页上的页眉
- 10月20日前!武汉市科技成果转化中试平台(基地)备案申报条件及流程梳理
- mac怎么修改hosts文件
- C++ 并发指南<future>(2)std::packaged_task
热门文章
- 随机信号分析第2版 [赵淑清郑薇编著] (部分)课后作业答案(自己写的)
- 应对 勒索病毒 补丁、免疫工具、关闭445端口
- CSRF和SSRF漏洞
- C# 把文件和文件夹 放到回收站 (出现Unknown err (0x402) 无法删除 文件:无法读取源文件或磁盘 解决)
- 【Python】实现商品信息管理系统(界面版,附带数据库)
- e580显卡驱动_联想e580网卡驱动下载|联想e580无线网卡驱动官方版_ - 极光下载站...
- p12解析流程_解析P12证书 | 学步园
- python打包生成so文件
- javashop源码百度云,java电商系统源码分享,Javashop多用户商城源码
- 一元线性回归(最小二乘法)