Java 8 中的List排序

2023-05-16

  • 按字母顺序排序字符串列表
List<String> cities = Arrays.asList(
       "Milan",
       "london",
       "San Francisco",
       "Tokyo",
       "New Delhi"
);
System.out.println(cities);
//[Milan, london, San Francisco, Tokyo, New Delhi]

cities.sort(String.CASE_INSENSITIVE_ORDER);
System.out.println(cities);
//[london, Milan, New Delhi, San Francisco, Tokyo]

cities.sort(Comparator.naturalOrder());
System.out.println(cities);
//[Milan, New Delhi, San Francisco, Tokyo, london]

Java 7中,我们使用Collections.sort对List进行排序,Collections.sort方法参数为ListJava 8中新增了一个集合方法List.sort,方法接受参数Comparator

  • 排序整数集合
List<Integer> numbers = Arrays.asList(6, 2, 1, 4, 9);
System.out.println(numbers); //[6, 2, 1, 4, 9]

numbers.sort(Comparator.naturalOrder());
System.out.println(numbers); //[1, 2, 4, 6, 9]
  • 按某个字符串属性列排序
List<Movie> movies = Arrays.asList(
        new Movie("Lord of the rings"),
        new Movie("Back to the future"),
        new Movie("Carlito's way"),
        new Movie("Pulp fiction"));

movies.sort(Comparator.comparing(Movie::getTitle));

movies.forEach(System.out::println);

结果输出

Movie{title='Back to the future'}
Movie{title='Carlito's way'}
Movie{title='Lord of the rings'}
Movie{title='Pulp fiction'}

我们注意到,给sort方法传递的并非Comparator类型,但结果仍然正确排序,原因就在于我们比较的属性列是String,而String已经实现了Comparable接口,查看Comparator.comparing()的定义实现,我们可以看到其其调用的就是比较关键字的compareTo方法

return (Comparator<T> & Serializable)
            (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
  • 按Double类型排序
List<Movie> movies = Arrays.asList(
        new Movie("Lord of the rings", 8.8),
        new Movie("Back to the future", 8.5),
        new Movie("Carlito's way", 7.9),
        new Movie("Pulp fiction", 8.9));

movies.sort(Comparator.comparingDouble(Movie::getRating)
                      .reversed());

movies.forEach(System.out::println);

本质上,Comparator.comparingDouble()调用的还是Double.compare()的方法,同样类似的还有comparingInt()comparingLong()方法

  • 自定义比较规则

比如,对于我们之前提到的Movie,这里我们需要按星标排序,那么我们可以自定义Comparator实现类

List<Movie> movies = Arrays.asList(
        new Movie("Lord of the rings", 8.8, true),
        new Movie("Back to the future", 8.5, false),
        new Movie("Carlito's way", 7.9, true),
        new Movie("Pulp fiction", 8.9, false));

movies.sort(new Comparator<Movie>() {
    @Override
    public int compare(Movie m1, Movie m2) {
        if(m1.getStarred() == m2.getStarred()){
            return 0;
        }
        return m1.getStarred() ? -1 : 1;
     }
});

movies.forEach(System.out::println);

得到输出结果如下:

List<Movie> movies = Arrays.asList(
        new Movie("Lord of the rings", 8.8, true),
        new Movie("Back to the future", 8.5, false),
        new Movie("Carlito's way", 7.9, true),
        new Movie("Pulp fiction", 8.9, false));

movies.sort(new Comparator<Movie>() {
    @Override
    public int compare(Movie m1, Movie m2) {
        if(m1.getStarred() == m2.getStarred()){
            return 0;
        }
        return m1.getStarred() ? -1 : 1;
     }
});

movies.forEach(System.out::println);

当然,我们也可以Lambda表达式以匿名类简写如下:

movies.sort((m1, m2) -> {
    if(m1.getStarred() == m2.getStarred()){
        return 0;
    }
    return m1.getStarred() ? -1 : 1;
});

或者通过Comparator.comparing()方法

movies.sort(Comparator.comparing(Movie::getStarred, (star1, star2) -> {
    if(star1 == star2){
         return 0;
    }
    return star1 ? -1 : 1;
}));
  • chain of Comparator排序集合

还是上面的例子,如果我们需要首先按电影星标,然后再按评分高低排序,那么我们可以通过如下方式实现。

List<Movie> movies = Arrays.asList(
        new Movie("Lord of the rings", 8.8, true),
        new Movie("Back to the future", 8.5, false),
        new Movie("Carlito's way", 7.9, true),
        new Movie("Pulp fiction", 8.9, false));

movies.sort(Comparator.comparing(Movie::getStarred)
                      .reversed()
                      .thenComparing(Comparator.comparing(Movie::getRating)
                      .reversed())
);

movies.forEach(System.out::println);

我们可以得到排序结果如下:

Movie{starred=true, title='Lord of the rings', rating=8.8}
Movie{starred=true, title='Carlito's way', rating=7.9}
Movie{starred=false, title='Pulp fiction', rating=8.9}
Movie{starred=false, title='Back to the future', rating=8.5}

原文链接:

https://reversecoding.net/java-8-comparator-how-to-sort-a-list/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 8 中的List排序 的相关文章

  • 使用 java 删除 XML 根的子级

    这是我的 xml 文件
  • 如何在ArrayList中的特定位置插入对象

    假设我有一个大小为 n 的对象的 ArrayList 现在我想在特定位置插入另一个对象 假设在索引位置 k 大于 0 且小于 n 并且我希望索引位置 k 处及其之后的其他对象向前移动一个索引位置 那么有没有什么方法可以直接在Java中做到这
  • 了解 netty 通道缓冲区和水印

    我正在尝试了解网络缓冲区和水印 作为一个测试用例 我有一个 netty 服务器 它向客户端写入数据 客户端被阻止 基本上每次读取之间有 10 秒的睡眠时间 在正常 I O 下 如果接收方被阻塞 TCP 发送方将受到限制 由于流量控制 发送速
  • 是否可以使用 Java 读写 Parquet,而不依赖 Hadoop 和 HDFS?

    我一直在寻找这个问题的解决方案 在我看来 如果不引入对 HDFS 和 Hadoop 的依赖 就无法在 Java 程序中嵌入读写 Parquet 格式 它是否正确 我想在 Hadoop 集群之外的客户端计算机上进行读写 我开始对 Apache
  • 为什么通过 方法向 List 添加元素(类型正确)会出现编译错误? [复制]

    这个问题在这里已经有答案了 我对泛型通配符概念几乎没有疑问 1 假设我有一个方法 void write List
  • 向前和向后迭代

    我们有一个双端结构列表 例如LinkedList 我需要向前和向后迭代元素 例如 向前 4 次 然后向后 2 次 然后向前 5 次 在 C 中它将是 iter iter iter 在 Rust 中 我只看到 next and rev 这很不
  • 未注入带有 JPA2 的 Apache Ignite 2.7 IgniteRepository

    使用在 Web 上建立的 guildes 我使用 Spring Data JPA 2 应用程序制作了简单的 Spring Boot 2 仅在 2 7 版本中才向 Apache Ignite 添加了 Spring Boot JPA 2 支持
  • 如何避免Eclipse在将类名放在注释中时导入类,以便checkstyle稍后不会抱怨?

    有时我将类名放在方法或类的注释中只是为了引用 但是 Eclipse 会自动执行导入并在文件中留下导入语句 这会导致稍后出现 未使用的导入 检查样式错误 当我在注释中输入类名时 是否可以更改一些配置以避免 Eclipse 自动导入 人们不同意
  • 对对象集合进行排序[重复]

    这个问题在这里已经有答案了 如果我有一个简单的字符串列表 List
  • Java 中如何验证字符串的格式是否正确

    我目前正在用 Java 编写一个验证方法来检查字符串是否是要更改为日期的几种不同格式之一 我希望它接受的格式如下 MM DD YY M DD YY MM D YY 和 M D YY 我正在测试第一种格式 每次它都告诉我它无效 即使我输入了有
  • 如何在 Eclipse 中获得完全限定的类名?

    有没有一种快速方法可以在 Eclipse 中单击 Java 类并获取其完全限定名称 或将其复制到剪贴板 2016年6月29日编辑 正如 Jeff 所指出的 您只需要执行以下第二步 1 Double click on the class na
  • 避免 @Secured 注释的重复值

    我正在尝试使用以下方法来保护我的服务方法 Secured如下 public interface IUserService Secured ROLE ROLE1 ROLE ROLE2 ResponseEntity saveUser Creat
  • RxJava android mvp 单元测试 NullPointerException

    我是 mvp 单元测试的新手 我想对演示者进行一个非常基本的测试 它负责登录 我只想断言 view onLoginSuccess 这是演示者代码 public LoginPresenter LoginViewContract loginVi
  • 了解Kafka流groupBy和window

    我无法理解 kafka 流中的 groupBy groupById 和窗口的概念 我的目标是聚合一段时间内 例如 5 秒 的流数据 我的流数据看起来像 value 0 time 1533875665509 value 10 time 153
  • Java 8 方法签名不一致

    Java 8 为我们提供了具有很长签名的新方法 如下所示 static
  • 获取 Future 对象的进度的能力

    参考 java util concurrent 包和 Future 接口 我注意到 除非我弄错了 只有 SwingWorker 实现类才能启动冗长的任务并能够查询进度 这就引出了以下问题 有没有办法在非 GUI 非 Swing 应用程序 映
  • 获取所有ios应用程序的全局列表[重复]

    这个问题在这里已经有答案了 我想对苹果应用商店进行一些全球统计 一个瓶颈是至少获取所有当前活动应用程序的 ID 这 9 位数字 有谁知道如何获取 iOS 应用商店中当前活动应用程序的所有 id 的完整列表 更好的是特定类别的所有 ID 例如
  • Firebase:用户注册后如何进行电话号码验证?

    所以我知道我可以使用电子邮件验证或电话号码验证 但我想做的是在用户注册或登录后进行电话号码验证 如何连接这两种身份验证方法 最后 Firebase中是否有一个函数可以检查用户是否通过电话号码验证 谢谢 即使用户已通过身份验证 您仍然可以使用
  • 从 InputStream 中删除换行符

    我喜欢从一个文件中删除所有换行符 对于 n 和 r n java io InputStream 在读取文件时 相应的方法如下所示 param target linkplain File return linkplain InputStrea
  • Java时区混乱

    我正在运行 Tomcat 应用程序 并且需要显示一些时间值 不幸的是 时间快到了 还有一个小时的休息时间 我调查了一下 发现我的默认时区被设置为 sun util calendar ZoneInfo id GMT 08 00 offset

随机推荐

  • setTimeout()和setInterval()详解

    JavaScript是单线程语言 xff0c 但是它可以通过设置超时值和间歇时间值来指定代码在特定的时刻执行 超时值是指在指定时间之后执行代码 xff0c 间歇时间值是指每隔指定的时间就执行一次代码 超时调用 超时调用使用window对象的
  • Centos 7.6安装Xfce+VNC Server

    Centos 7 6安装Xfce 43 VNC Server 工作环境安装xface安装 VNC Server在云服务器控制台中设置安全组规则使用VNC Viewer连接云服务器 工作环境 华为云服务器 操作系统 xff1a CentOS
  • C++和C语言的区别是什么?

    首先C 43 43 和C语言本来就是两种不同的编程语言 xff0c 但C 43 43 确实是对C语言的扩充和延伸 xff0c 并且对C语言提供后向兼容的能力 C 43 43 这个词在中国大陆的程序员圈子中通常被读做 C加加 xff0c 而西
  • ubuntu18.0.4安装pip3及虚拟环境virtualenv详细教程

    1 ubuntu安装pip3 该命令是修复安装及补全那些缺少的软件 xff1a sudo apt get f install 安装pip3 xff1a sudo apt get install python3 pip升级pip3 xff1a
  • 什么是子网掩码,如何判断两个IP是不是同一网段

    1 xff1a 什么是子网掩码 xff1f 子网掩码不能单独存在 xff0c 它必须结合IP地址一起使用 子网掩码只有一个作用 xff0c 就是将某个IP地址划分成网络地址和主机地址两部分 说的通俗的话 xff0c 就是用来分割子网和区分那
  • 利用esp-8266实现wifi攻击

    0x00 前言 之前在b站上看到这个wifi模块的攻击视频感觉挺有意思 xff0c 就在某宝上入了一个拿回来玩玩 0x01 外观 转接头需要自己另外买 0x03 编译程序 https anky cc esp8266 deauther wif
  • 如何从 JavaScript 对象中删除属性?

    问题描述 xff1a 给定一个对象 xff1a let myObject span class token operator 61 span span class token punctuation span span class toke
  • 在 Git 中推送提交时消息“src refspec master does not match any”

    问 xff1a 我克隆我的存储库 xff1a git clone ssh span class token operator span span class token operator span span class token oper
  • Qt编译、链接和运行参数的设置

    Qt编译 链接和运行参数的设置 Qt笔记 使用 Qt Creator 集成开发环境构建和运行程序是一件非常简单的事情 xff0c 一个按钮或者一个快捷键搞定全部 xff0c 通过 Qt Creator使用教程 xff08 简明版 xff09
  • 常用Linux命令行技巧

    结果以表格形式输出 column t 比如 xff1b span class token function mount span span class token operator span column t 默认分隔符为空格 xff0c
  • CV往哪卷?李飞飞指出三颗「北极星」:具身智能,视觉推理和场景理解

    点击下方卡片 xff0c 关注 CVer 公众号 AI CV重磅干货 xff0c 第一时间送达 转载自 xff1a 新智元 编辑 xff1a LRS 导读 ImageNet见证了计算机视觉发展的辉煌历程 xff0c 在部分任务性能已超越人类
  • Java异常处理的九个最佳实践

    1 确保在Finally程序块中完成资源释放或者使用Try With语句 比如对于InputStream xff0c 当我们使用完毕 xff0c 我们要确保资源被正确关闭 xff0c 比如下面我们常见的错误用法 xff0c 不要在try模块
  • CodeMirror使用笔记

    最近因工作需要 xff0c 在项目中使用了CodeMirror代码编辑器 xff0c 以下是使用笔记 首先 xff0c 看下最终的效果 引入基本的需要资源 lt script src 61 34 lt 61 request getConte
  • JAVA注解

    Java注解Annotations主要用于为目标程序提供额外补充的说明信息 注解以 64 符号标识注解并不改变编译程序的行为注意可以为程序元素 xff1a 实例变量 构造方法 方法或者类添加元数据信息注解并不是单纯的注释 xff0c 但却可
  • ubuntu中GitLab的安装与配置

    这里 xff0c 我们采用离线安装的方式安装GitLab 首先 xff0c 我们从清华大学开源软件镜像站中下载软件包 xff0c 用户可根据实际的服务器操作系统版本来选择不同的镜像资源 xff0c 这里我们以ubuntu为例 执行命令sud
  • Jenkins使用笔记

    本章简单记录Jenkins的使用笔记 首先 xff0c 我们从官网中下载安装介质 xff0c 可以看到这里有适合各种操作系统版本的安装源介质 xff0c 简单起见 xff0c 我们直接下载一个通用的war程序包 执行命令java jar j
  • GitLab 与 Jenkins 持续集成实践

    首先 xff0c 我们简单说明下我们的部署环境 xff1a GitLab xff1a 192 168 43 61 Jenkins xff1a 192 168 43 116 Jenkins中系统设置中 xff0c 配置GitLab连接信息 x
  • Linux下免密认证登录失败原因总结

    事件背景 A机器已经生产rsa密钥且已经将public key添加到B机器 root ssh authorized keys xff0c 但是从A机器上ssh root 64 B机器时仍然需要输入密码 xff0c 即无密码认证失败 原因总结
  • 公钥添加到authorized_keys到文件中之后仍无法免密登陆

    接上一章 xff0c 关于Linux下免密登陆失败 xff0c 这里找了Stackoverflow上关于这个问题的讨论 xff1a Adding public key to ssh authorized keys does not log
  • Java 8 中的List排序

    按字母顺序排序字符串列表 List lt String gt cities 61 Arrays asList 34 Milan 34 34 london 34 34 San Francisco 34 34 Tokyo 34 34 New D