Java List排序 java ListMap 排序 Java listmap 模拟 oracle 排序 Java listmap 模拟 mysql 排序

一、概述

近期的开发工作中,遇到一个需求: 对 Listmap的结果集进行排序,类似于模拟 数据库中的Order By 排序。那么主要的需求有: 排序方式 ASC/DESC ; null 值处理:NULL FIRST / NULL LAST 。 在Java 中要实现以上相应的功能,对List进行排序,会遇到对应问题: 元素中有 null ,排序时候会抛出 NPE 、 null 元素放在 最前、最后面的问题。

本文将基于Java8,逐一演示,上述中出现问题的对应示例代码;最终给出 List<Map> 排序的解决方案,实现易用性,通用性。

二、问题

1、元素有null,排序处理:

/*** Description: null 值处理* <br> 1. null 元素,排序 NPE* <br> 2. 解决: null 放在最前面、最后面* @param* @return void* @version v1.0* @author wu* @date 2022/10/17 15:43*/@Testpublic void nullListTest(){ArrayList<String> list = Lists.newArrayList("22","33",null,"11");System.out.println("nullListTest  排序前:" + list);// list中有 null 元素,排序会抛出 NPElist.sort(Comparator.comparing(e->e)); // 抛出 NPElist.sort((e1,e2)->e1.compareTo(e2)); // 抛出 NPE
//        list.sort(Comparator.comparing(String::valueOf)); // 避免npe// null 值处理: null 放在最前list.sort(Comparator.comparing(e->e,Comparator.nullsFirst(String::compareTo)));System.out.println("nullListTest  排序后: null 放在最前:" + list);// null 值处理: null 放在最后list.sort(Comparator.comparing(e->e,Comparator.nullsLast(String::compareTo)));System.out.println("nullListTest  排序后:null 放在最后:" + list);}

1.1、输出结果:

nullListTest  排序前:[22, 33, null, 11]java.lang.NullPointerException
...

2、倒序 DESC时,null 值放在 最前面、最后面的处理

/*** Description: 倒序的时候, null 值处理* <br> 1. null 最前面: nullsLast 方法* <br> 2. null 最后面: nullsFirst 方法* @return void* @version v1.0* @author wu* @date 2022/10/17 16:37*/@Testpublic void nullDESCTest() throws Exception{ArrayList<String> list = Lists.newArrayList("22","33",null,"11");System.out.println("nullDESCTest  排序前:" + list);// DESC ,  null  first
//        list.sort(Comparator.comparing((String e)->e,Comparator.nullsFirst(String::compareTo)).reversed());list.sort(Comparator.comparing((String e)->e,Comparator.nullsLast(String::compareTo)).reversed());System.out.println("nullDESCTest  DESC ,  null  first :" + list);// DESC ,  null  lastlist.sort(Comparator.comparing((String e)->e,Comparator.nullsFirst(String::compareTo)).reversed());System.out.println("nullDESCTest  DESC ,  null  last :" + list);}

2.1、输出结果:

nullDESCTest  排序前:[22, 33, null, 11]
nullDESCTest  DESC ,  null  first :[null, 33, 22, 11]
nullDESCTest  DESC ,  null  last :[33, 22, 11, null]

3、数字是字符串类型时,排序不对的问题:

  /*** Description: 字符串类型数字 排序* <br> 解决:字符串转换为数字,进行排序* @return void* @version v1.0* @author wu* @date 2022/10/17 15:44*/@Testpublic void strNumTest() throws Exception{List<String> list = Lists.newArrayList("10","11","101","111");System.out.println("strNumTest  排序前:" + list);// 倒序排序list.sort(Comparator.comparing(String::valueOf).reversed());
//        list.sort(Comparator.comparing((String e)->Integer.valueOf(e)).reversed()); // 解决排序不对的问题System.out.println("strNumTest  排序后:" + list);}

3.1、输出结果是:

strNumTest  排序前:[10, 11, 101, 111]
strNumTest  排序后:[111, 11, 101, 10]

三、解决 --- 通用排序方案

1、上述代码中,演示了可能出现的问题,以及对应的解决方案:

  • 元素中有null , 使用 Comparator.nullsFirst / Comparator.nullsLast
  • 倒序时null元素 处理: 最前面 --- Comparator.nullsLast ; 最后面 --- Comparator.nullsFirst
  • 数字是字符串类型时: 转换为数字进行排序

2、List<Map<String,Object>> 排序可能遇到问题:

  • 排序字段不确定
  • 排序字段类型不确定
  • 排序方式不确定
  • 可能 出现null元素

3、经整理汇总后,通用排序流程如下:

4、定义一个 ListMapConfig 配置类 ,统一维护相关的配置:

/*** Description: List Map 排序 配置* @author w* @version 1.0* @date 2022/10/17 16:09*/
public class ListMapConfig {private String orderProperty ; // 排序字段:private String porpertyType = "STRING"; // 属性类型: STRING / NUMBERprivate String orderMode ="ASC"; // 排序方式: ASC/DESCprivate String orderModeNull ="LAST"; // null值处理: FIRST / LASTpublic static ListMapConfig getDefault(){return new ListMapConfig();}// ignore getter / setter
}

5、通用的 ListMap排序方法:

public static void processSort(List<Map<String, Object>> listMap , ListMapConfig config){String orderProperty = config.getOrderProperty();Assert.isTrue(StringUtils.isNotBlank(orderProperty));if("NUMBER".equals(config.getPorpertyType())){// 数字 类型排序if("DESC".equals(config.getOrderMode())){if("FIRST".equals(config.getOrderModeNull())){listMap.sort(Comparator.comparing((Map e)->{Object val = e.get(orderProperty);return val == null ? null : Double.valueOf(val.toString());// 倒序时,null值放在最后,反过来:需要用 nullsLast},Comparator.nullsLast(Double::compareTo)).reversed());}else {listMap.sort(Comparator.comparing((Map e)->{Object val = e.get(orderProperty);return val == null ? null : Double.valueOf(val.toString());// 倒序时,null值放在最后,反过来:需要用 nullsFirst},Comparator.nullsFirst(Double::compareTo)).reversed());}}else {if("FIRST".equals(config.getOrderModeNull())){listMap.sort(Comparator.comparing((Map e)->{Object val = e.get(orderProperty);return val == null ? null : Double.valueOf(val.toString());},Comparator.nullsFirst(Double::compareTo)));}else {listMap.sort(Comparator.comparing((Map e)->{Object val = e.get(orderProperty);return val == null ? null : Double.valueOf(val.toString());},Comparator.nullsFirst(Double::compareTo)));}}}else if("STRING".equals(config.getPorpertyType())){// 字符串 类型排序if("DESC".equals(config.getOrderMode())){if("FIRST".equals(config.getOrderModeNull())){listMap.sort(Comparator.comparing((Map e) -> {Object val =  e.get(orderProperty);return null == val ? null : val.toString();// 倒序时,null值放在最后,反过来:需要用 nullsLast},Comparator.nullsLast(String::compareTo)).reversed());}else {listMap.sort(Comparator.comparing((Map e) -> {Object val =  e.get(orderProperty);return null == val ? null : val.toString();// 倒序时,null值放在最后,反过来:需要用 nullsFirst},Comparator.nullsFirst(String::compareTo)).reversed());}}else {if("FIRST".equals(config.getOrderModeNull())){listMap.sort(Comparator.comparing((Map e) -> {Object val =  e.get(orderProperty);return null == val ? null : val.toString();},Comparator.nullsFirst(String::compareTo)));}else {listMap.sort(Comparator.comparing((Map e) -> {Object val =  e.get(orderProperty);return null == val ? null : val.toString();},Comparator.nullsLast(String::compareTo)));}}}
}

四、代码测试

1、创建一个 ListMapSortTest2 测试类:

public class ListMapSortTest2 {static   List<Order> orderList =  null;static  List<Map<String,Object>> listMap = null;public static void main(String[] args) {init();System.out.println(orderList);// 1、转换为maplistMap = com.google.common.collect.Lists.newArrayList();for (Order e : orderList) {JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(e));Map map = JSON.toJavaObject(jsonObject, Map.class);listMap.add(map);}System.out.println("listMap :"+listMap);ListMapConfig config = ListMapConfig.getDefault();config.setOrderProperty("appNo");// STRING-TEST1: ASC - NULL FIRSTconfig.setOrderModeNull("FIRST");processSort(listMap,config);System.out.println("STRING-TEST1: ASC - NULL FIRST : " + listMap);// STRING-TEST2: ASC - NULL LASTconfig.setOrderModeNull("LAST");processSort(listMap,config);System.out.println("STRING-TEST2: ASC - NULL LAST : " + listMap);// STRING-TEST3: DESC - NULL FIRSTconfig.setOrderModeNull("FIRST");config.setOrderMode("DESC");processSort(listMap,config);System.out.println("STRING-TEST3: DESC - NULL FIRST : " + listMap);// STRING-TEST4: DESC - NULL LASTconfig.setOrderModeNull("LAST");config.setOrderMode("DESC");processSort(listMap,config);System.out.println("STRING-TEST4: DESC - NULL LAST : " + listMap);}private static void init() {orderList = Lists.newArrayList();orderList.add(new Order(1,"小明","203"));orderList.add(new Order(2,"小红",null));orderList.add(new Order(3,"小刚","404"));}static class Order {private Integer id;private String name;private String appNo;public Order(Integer id, String name, String appNo) {this.id = id;this.name = name;this.appNo = appNo;}public Order() {}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAppNo() {return appNo;}public void setAppNo(String appNo) {this.appNo = appNo;}@Overridepublic String toString() {return "Order{" +"id=" + id +", name='" + name + '\'' +", appNo='" + appNo + '\'' +'}';}}
}

3、注意:Number类型,未测试!

五、总结

1、本文初步解决 List<Map> 集合的排序问题,因 map集合中元素类型的不确定性,所以 当前写了2种排序方式:统一按照字符串排序 或者 数字类型 ; 在 ListMapConfig.porpertyType 中,可以添加 相应的其他类型,进行功能扩展 。 比如: java.util.Date 类型处理。

2、ListMapConfig 类中,porpertyType 等属性,可以定义为 枚举类型, 便于更好的理解,和后续扩展。

3、通用排序方法:processSort , 写了太多的 if else , 可以引入设计模式,更加优雅!

排序相关的文章资料参考:

使用MySQL FIELD函数实现自定义排序 特定字段排序 指定字段排序_HaHa_Sir的博客-CSDN博客

Java List集合排序 Java8 List集合排序方法 Java Lambda集合排序_HaHa_Sir的博客-CSDN博客_java8 集合排序

Oracle 中文排序 Oracle 中文字段排序_HaHa_Sir的博客-CSDN博客_oracle 中文排序

Java List排序 java ListMap 排序 Java listmap 模拟 oracle 排序 Java listmap 模拟 mysql 排序相关推荐

  1. oracle java认证_如何通过Oracle的Java认证-开发人员实用指南

    oracle java认证 by javinpaul 由javinpaul 如何通过Oracle的Java认证-开发人员实用指南 (How to Pass Oracle's Java Certific ...

  2. 免登陆从Oracle下载Java SE

    一,为何会有这篇博文 因为某些原因,从orcale官网下载Java SE很慢,并且需要注册ocacle账户. 目前没有找到其他的安全有效的下载源. 看不下去orcale这么能作,帮助一下苦难的萌新程序 ...

  3. 收购后Java之父首次公开亮相 称Oracle掌管Java令人放心

    在Oracle收购Sun Microsystems之后,Java之父James Gosling首度在公开场合露面,他一如既往保持着对Java的高度关注,并表示Java在Oracle的掌管下令人放心,随 ...

  4. oracle 中文拼音取首字母,ORACLE依据中文拼音首字母排序、取得中文拼音首字母函数...

    当前位置:我的异常网» 数据库 » ORACLE依据中文拼音首字母排序.取得中文拼音首字母 ORACLE依据中文拼音首字母排序.取得中文拼音首字母函数 www.myexceptions.net  网友 ...

  5. java array 元素的位置_数据结构与算法:动态图解十大经典排序算法(含JAVA代码实现)...

    点击上方"JAVA",星标公众号 重磅干货,第一时间送达 本文将采取动态图+文字描述+正确的java代码实现来讲解以下十大排序算法: 冒泡排序 选择排序 插入排序 希尔排序 归并排 ...

  6. java编写排序的代码_在Java 8之前,您编写了几行代码来对对象集合进行排序?...

    java编写排序的代码 在Java 8之前,您编写了几行代码来对对象集合进行排序? Java 8您需要多少个? 您可以在Java 8中用一行完成. 让我们看看下面的Employee类. public ...

  7. 在Java 8之前,您编写了几行代码来对对象集合进行排序?

    在Java 8之前,您编写了几行代码来对对象集合进行排序? Java 8您需要多少个? 您可以在Java 8中用一行完成. 让我们看看下面的Employee类. public class Employ ...

  8. 微信字典排序java_【支付宝,微信支付必备】Java实现url参数按照参数名ASCII码从小到大排序(字典序)...

    /** * * 方法用途: 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序),并且生成url参数串 * 实现步骤: * * @param paraMap 要排序的Map对象 * @pa ...

  9. java中list里面存放map,根据map中的某一个字段进行排序

    Java中list里面存放map,根据map中的某一个字段进行排序 例如: [java] view plaincopy package com; import java.util.ArrayList; ...

最新文章

  1. PHP二维数组去除重复值
  2. A.2.3-猜数字游戏
  3. 异常检测算法分类及经典模型概览
  4. mngoDB 常用语法
  5. 跨平台开发与原生开发优劣比较
  6. glog 编译报错 ERROR macro is defined. Define GLOG_NO_ABBREVIATED_SEVERITIES before including logging.h.
  7. 【渝粤教育】国家开放大学2019年春季 2610药剂学 参考试题
  8. java 中的radix_线程“main”中的异常java.lang.NumberFormatException:Radix超出范围
  9. Shell中$X的含义
  10. vs2015无法编辑html,连发Lianfa娱乐app -连发Lianfa娱乐appV6.2.84
  11. 微信小程序如何实现登陆功能
  12. 备案域名基础知识,网站备案新政策
  13. Postgresql 之 数据库认证
  14. P2P分布式搜索引擎YaCy
  15. [!] CocoaPods was not able to update the `xxx` repo. If this is an unexpected issue and persists
  16. 【现代通信原理笔记】4 数字基带传输
  17. win10清理c盘_只需十步,C盘轻松腾出30G!使用win10自带工具清理系统垃圾,让电脑重获新生...
  18. MySQL8.0登录提示caching_sha2_password问题解决方法
  19. SAP系统中信用控制功能详解
  20. ADI-trinamic精确控制医疗设备(IVD体外诊断仪器)

热门文章

  1. 机器学习:随机森林原理 OOB等
  2. 特征提取与检测6-SURF特征检测
  3. java java java java
  4. C# StatusBar
  5. java long string 转换_Java long 转成 String的实现
  6. OpenCL Installable Client Driver (ICD) Loader编译
  7. c++ 求x的n次方
  8. smil_SMIL简介-鞋串上的多媒体演示
  9. 深度解析SQL和NoSQL数据库,掌握主流数据库【两万字解析】
  10. SD-Host SD_CLK模块