Java stream流支持多字段排序

【光学仿真】基于Matlab的LG/BG/PV/HG光束生成与特性分析【附完整源码】 本文详细介绍了如何使用Matlab进行拉盖尔-高斯(LG)、贝塞尔-高斯(BG)、完美涡旋(PV)和厄米-高斯(HG)四种特殊光束的仿真与特性分析。通过提供完整的Matlab源码,手把手指导读者生成光束、分析其强度、相位、传播特性及轨道角动量,为光学研究、激光应用及教学提供了直观高效的数值实验平台。 阅读详情

背景

对于排序而言,比较常见的场景是前端传递所需的排序字段名和排序方向,然后通过stream流或者数据库来实现排序.
为动态接收参数,继承Map来支持多字段传入.另外stream流原生的sorted写起来相对比较繁琐,可以通过compartor方法封装构建多字段排序的逻辑进行简化.具体实现就是通过反射拿到对应字段的值,然后利用Compartor的comparing和thenComparing完成多字段排序.

代码

具体代码和测试结果如下

package com.mamu.funnyair.model.common;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import cn.hutool.core.util.ReflectUtil;
import lombok.Data;

/**
 * 封装Map接收前端排序参数,并提供compartor,方便构建stream流sorted所需的Comparator
 * <pre>
 *     示例:
 *     {
 *         "fieldName": "ascend",
 *         "fieldName2": "descend"
 *     }
 * </pre>
 *
 * <pre>
 *     1. key 是排序字段
 *     2. value 是排序方向,可选值 ascend/descend 或者 asc/desc
 *     3. 排序字段属性需符合java的get规范,其中使用了反射获取field对应的get方法
 *     4. 排序字段的类型必须实现Comparable接口,否则抛出异常The field xx does not implement Comparable interface
 *     5. 注意这里用的是LinkedHashMap,保证排序参数的顺序.如果是HashMap,排序参数的顺序可能会丢失,甚至反过来
 *     6. 依赖了hutool的ReflectUtil,后续尽量移除此依赖
 * </pre>
 *
 * @author yi qiang
 * @date 2024-07-23 16:28:52
 */
@SuppressWarnings("all")
public class SortMap extends LinkedHashMap<String, String> {

    /**
     * 根据排序参数构建Comparator
     */
    public <T> Comparator<T> compartor() {
        if (this.isEmpty()) {
            return null;
        }
        Comparator<T> comparator = null;
        // 遍历排序参数,构建comparator
        // 可以用reduce,但是感觉还没三元表达式清晰
        for (Map.Entry<String, String> entry : this.entrySet()) {
            comparator = (comparator == null) ?
                         getTempComparator(entry.getKey(), entry.getValue()) :
                         //多字段排序,第二个字段开始就要使用thenComparing
                         comparator.thenComparing(getTempComparator(entry.getKey(), entry.getValue()));
        }
        return comparator;
    }

    private Comparator getTempComparator(String fieldName, String direction) {
        if ("descend".equalsIgnoreCase(direction) || "desc".equalsIgnoreCase(direction)) {
            return Comparator.comparing(getKeyExtractor(fieldName), Comparator.reverseOrder());
        }
        return Comparator.comparing(getKeyExtractor(fieldName));
    }

    /**
     * 排序属性值的映射函数
     */
    private Function getKeyExtractor(String fieldName) {
        return ele -> {
            Object o = ReflectUtil.getFieldValue(ele, fieldName);
            if (o instanceof Comparable) {
                return (Comparable) o;
            }
            throw new RuntimeException("The field " + fieldName + " does not implement Comparable interface");
        };
    }
    // 暂时未经过严格测试,比如父类属性,先不处理
    //    private static Object getFieldValue(Object ele,String fieldName) {
    //        try {
    //            Field declaredField = ele.getClass().getDeclaredField(fieldName);
    //            declaredField.setAccessible(true);
    //            return declaredField.get(ele);
    //        } catch (Exception ex) {
    //            return null;
    //        }
    //    }

    public static void main(String[] args) {
        List<Test> tests = new ArrayList<>();
        Test test = new Test();
        test.setL(1);
        test.setDate(new Date());
        test.setS("c");
        tests.add(test);

        Test test1 = new Test();
        test1.setL(2);
        test1.setDate(new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24));
        test1.setS("a");

        tests.add(test1);

        Test test2 = new Test();
        test2.setL(2);
        test2.setDate(new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24));
        test2.setS("b");
        test2.setTest2(new Test2());
        tests.add(test2);

        SortMap sortMap = new SortMap();
        sortMap.put("l", "descend");
        sortMap.put("s", "descend");
        //测试Comparable接口未实现
        //sortMap.put("test2", "ascend");

        //此处看到泛型也是生效的,可以自动识别成对应的类
        List<Test> collect = tests.stream().sorted(sortMap.compartor()).collect(Collectors.toList());

        collect.forEach(System.out::println);
    }

    @Data
    public static class Test {
        private long l;
        private String s;
        private Date date;
        private Test2 test2;
    }

    @Data
    public static class Test2 {
        private long l;
        private String s;
    }
}

运行结果
在这里插入图片描述
如果此工具能帮到大家,请动动手点个赞.

低代码Agent开发框架使用指南(二)—Coze平台核心功能概览 本篇分享系统介绍了字节跳动推出的低代码智能体开发平台Coze。Coze以免费易用、多模型支持和便捷的跨平台发布为核心优势,显著降低了智能体开发门槛。文章详细解析了平台的六大核心功能:扩展能力边界的插件系统、增强认知的知识库、结构化数据管理的数据库、可视化图像处理的图像流、实现复杂逻辑编排的工作流,以及处理复杂任务的多智能体协作机制,全面展现了Coze平台的强大能力。 阅读详情

相关推荐

手把手教你用QEMU模拟AST2600-EVB开发板:OpenBMC环境搭建全流程

本文提供了一份详尽的实战指南,手把手教你使用QEMU模拟器搭建AST2600-EVB开发板的OpenBMC环境。内容涵盖从工具链准备、系统镜像获取(官方与自编译),到QEMU启动命令解析、网络配置(用户与桥接模式),以及通过SSH、WebUI和Redfish API访问服务的全流程,帮助开发者在个人电脑上快速构建安全、可复现的嵌入式开发与测试沙盒。

play7的博客 1134

stream流多字段排序SpringBoot

Java8之stream流多字段排序

shyの个人笔记 1万+

SAP开发实战:用FI_DOCUMENT_CHANGE BAPI批量修改FB03凭证抬头和行项目文本(附完整ABAP代码)

本文详细介绍了如何使用SAP的FI_DOCUMENT_CHANGE BAPI批量修改FB03凭证抬头和行项目文本,提供完整的ABAP代码实现方案。通过该BAPI,开发者可以高效完成财务凭证的批量修改,确保数据一致性和审计合规性,显著提升SAP财务模块的运维效率。

weixin_29224589的博客 386

Java的stream流多个字段排序

【代码】Java的stream流多个字段排序。

tanqingfu1的博客 1582

KEIL-MDK代码美化神器:AStyle配置全攻略(附常用参数详解)

本文详细介绍了如何在KEIL-MDK中配置和使用AStyle代码格式化工具,包括基础参数设置、高级格式控制、团队协作方案以及KEIL深度集成技巧。通过合理的AStyle配置,开发者可以显著提升代码风格一致性,优化团队协作效率,特别适合嵌入式开发项目。

weixin_30505225的博客 149

(2)NPW(监控片)【中】---业务场景精讲

自己在日常工作当中,由于非产线人员出生,对NPW的知识一直一知半解,业务场景认识的不够透彻,做系统的时候很难理解甲方的NPW业务应用,特收集了不少关于NPW的一些业务场景,下面都是一些摘抄,大家关注我标红标粗的部分,

阿拉伯梳子的专栏 1592

Java Stream流对多个字段进行排序

通过代码我们可以知道通过stream的sorted()方法就可实现我们想要的结果,原理还是利用Comparator比较器对要排序的字段进行比较,如果想倒序,则在比较器后面加上reversed(),该方法是对排序后的数据进行一个反转。谈起Java 8,不少熟悉它的人,都会知道有一个对我们帮助很多大新特性,没错,就是我们在项目中经常用到的stream,它在我们对数据的处理的过程中提供了很多的便利,而这边文章主要讲述stream的便利之一:对多个字段进行排序。

祖哥的博客 4564

「JS逆向三百例」JS逆向HIKVISION-视频监控的前端密码加密

本文详细分析了HIKVISION-海康威视监控前端登录过程中密码的加密机制,通过逆向工程解析了其 JavaScript 加密逻辑,重点研究了HIKVISION-海康威视监控的前端密码SHA256加密算法的实现。基于逆向分析结果,使用 Python 模拟了HIKVISION-海康威视监控的登录流程,最终实现了自动化登录功能。本文旨在为安全研究人员提供技术参考,帮助理解前端加密机制,并强调技术研究的合法性和合规性。

布啦啦 1100

JavaStream多字段排序

JavaStream多字段排序

qq_33719533的博客 2390

【华为OD机试真题 新系统】1029、字符串处理 | 机试真题+思路参考+代码解析(C++、Java、Py、C语言、JS)

【华为OD机试真题 新系统】1029、字符串处理 | 机试真题+思路参考+代码解析(C++、Java、Py、C语言、JS) 华为od机试,华为od机试真题,华为od机试E卷,华为odE卷,华为od机试真题E卷,华为OD,华为OD机试,华为OD机试真题,华为od机考,华为od机试D卷,华为od机试真题D卷,华为od手撕代码,华为od,华为od机试C卷,华为od e卷,华为2026e卷,od机试,2026E卷,华为OD机试E卷,什么是华为od,华为od介绍,全面了解华为od,2026华为od,如何备战华为od,

KJ.JK 221

DSI3协议介绍

分布式系统接口(DSI)是一种通用且功能强大的总线协议,旨在将多个遥感器和执行器设备互连到中央控制模块。该网络的主要目标应用是汽车安全系统。这种应用的一些特点是需要低成本、高鲁棒性、中速互连,仅限于两根导线。此外,它必须具有故障安全性、确定性和良好的EMC特性。即使具有所有级别的智能和可编程性的设备都可以连接到网络,远程设备也必须能够通过简单的状态机实现。由于模块尺寸非常重要,因此中央模块和远程单元中的最小组件至关重要。

汽车电子软件领域知识分享 1万+

Java stream使用流进行多字段排序

在开发过程中我们经常会遇到根据对象中不同字段的值进行排序,也就是我们常说的多字段排序。在中我们可以使用流很便捷的进行排序。下面我将以年龄和班级两个字段的值来演示使用流进行多字段排序的操作。 1.3 字段排序 1.3.1 单个字段排序 根据年龄升序排序 根据年龄降序排序 先以年龄升序,相同年龄的对班级进行升序年龄升序,班级升序 年龄降序,班级升序 年龄降序,班级降序 年龄升序,班级降序 如果只进行单个字段的升序降序排列,我们使用 或者 都可以 如果要进行多个字段的升

loveLifeLoveCoding的博客 4139

YOLOv11改进缝合注意力 | 深度优化的BiFormer模型-结合BiLevel Routing Attention与深度可分离卷积的创新应用(附代码)

YOLO(You Only Look Once)系列目标检测算法一直以来都是计算机视觉领域的热门选择。随着YOLOv11的发布,它在许多实际应用场景中取得了显著的性能提升。然而,面对日益复杂的目标检测任务,单纯依赖卷积神经网络(CNN)在某些情况下已经显得力不从心,特别是在处理小尺度、密集目标以及遮挡目标时,卷积操作的局部性限制了模型的表达能力。

一键难忘的博客 721

Java 8 Stream流排序完全解析(多字段排序最佳实践)

掌握Java 8 Stream流排序技巧,轻松实现多字段排序。详解sorted多字段排序写法,适用于集合数据复杂排序场景,提升代码可读性与性能。结合Comparator链式调用,灵活应对多种业务需求,值得收藏。

PixelWander的博客 561

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

揭秘Java Stream sorted多字段排序:3个你必须掌握的实战技巧

解决Java多字段排序难题,详解Java 8 Stream 流 sorted 多字段排序写法。涵盖Comparator链式调用、null安全处理及自定义比较逻辑,适用于列表去重、分页排序等真实场景。代码简洁、可读性强、性能优异,值得收藏。

QuickSolve的博客 712

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

【高级Java编程技巧】:利用Comparator链实现Stream多字段排序

掌握Java 8 Stream流多字段排序写法,轻松实现复杂数据排序需求。通过Comparator链在sorted中组合多个比较条件,适用于集合对象的多级排序场景,代码简洁且可读性强。利用thenComparing扩展排序规则,提升灵活性与维护性,高级开发必备技巧,值得收藏。

CodeNexus的博客 1014

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

如何用Java 8 Stream实现多字段排序?这4种方法你一定要知道

掌握Java 8 Stream流sorted多字段排序写法,轻松实现复杂数据排序需求。适用于集合多条件排序场景,支持Comparator链式调用、null值处理及逆序排序,代码简洁高效,值得收藏。

FuncInk的博客 571

Stream排序不止sorted:thenComparing让你掌控多字段优先级

掌握Java 8 Stream API 排序 thenComparing,轻松实现多字段优先级排序。适用于集合数据按多个条件排序的场景,通过thenComparing链式调用精准控制排序逻辑,代码简洁且可读性强。告别复杂比较器,提升开发效率,值得收藏。

simcode的专栏 783

Stream多字段排序不会?看完这篇立刻掌握核心技能

掌握Java 8 Stream流多字段排序写法,轻松实现复杂数据排序需求。适用于集合对象按多个属性排序的常见场景,通过Comparator链式调用实现灵活排序逻辑,代码简洁高效。一文搞懂sorted核心用法,值得收藏。

AlgoFun的博客 642

【Java 8 Stream排序进阶指南】:掌握多字段排序的5种高效写法

掌握Java 8 Stream流多字段排序写法,轻松实现复杂数据排序需求。适用于集合处理、报表排序等场景,详解Comparator链式调用与null值处理,提升代码可读性与性能,值得收藏。

SimSolve的博客 608

java 实现Stream排序(附带源码)

java 实现Stream排序(附带源码)

欢迎来到我的博客!这里是一个专注于计算机技术的分享平台,涵盖编程开发、算法研究、系统架构、软件工程等多个领域。无论你是初学者还是资深开发者,都能在这里找到有价值的内容。 939

Java Stream排序难题全破解(从单字段到多字段的优雅实现)

掌握Java 8 Stream 流 sorted 多字段排序写法,轻松实现复杂数据排序需求。适用于集合处理、报表排序等场景,通过Comparator链式调用实现多条件优先级排序,代码简洁高效。逻辑清晰,可读性强,Java开发者值得收藏。

ProceShoal的博客 696

Java8 stream 多条件排序,且支持自定义排序

需求:从数据库中查询到实体类的list,需要根据实体类中的某几个字段进行排序。 假设:实体类如下: static class SortExample{ private Integer id; private String region; private String fileType; private String fileCode; private String fileSize; ...

五行缺火 8821

别再写笨重的比较器了!Stream多字段排序这样写才够优雅

掌握Java 8 Stream流多字段排序写法,告别冗长比较器代码。适用于集合排序场景,通过thenComparing链式调用实现多条件排序,代码简洁易读。提升开发效率,让逻辑更清晰,值得收藏。

Algorhythm的博客 444

【JAVA】jdk8 Stream 排序精通

因为对象比基本类型占用空间大,如果排完序之后再翻转,而同时数组长度比较大,那么就可能有性能问题,所以可以直接指定排序的方向,避免不必要的浪费。但是对于完全的数值比较,其实就按照默认的比较即可,给Stream 排序的值即可,特别是对象,只需要指定字段即可。jdk8的stream流能方便的排序,但是每次都要查资料,非常不方便,不确定,所以这次直接弄懂,不再迷茫。,字符串比较很简单,就是字符依次比较,从小到大,第一位相同比第二位,依次排序。因此对象排序,优先使用这样的方式去指定排序,特别是倒序的时候。

weixin_41979605的博客 6114

[Stream使用(一)]对实体类集合按多字段进行排序(包括集合中该字段为null的对象)

测试类如下 package com; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; public class StreamOrderTest { public static void main(String[] args) { User user1 = new User("a",10,999.0)

qq_43504788的博客 1万+
上一篇: Linux常用命令总结
一步一结
博客等级 码龄7年 50粉丝 65原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值