java之使用stream對(duì)日期排序方式
java使用stream對(duì)日期排序
主要講解Stream對(duì)日期字段進(jìn)行排序時(shí)的寫法,以及當(dāng)日期字段為null時(shí)的排序策略?;蛘邔?duì)多個(gè)屬性進(jìn)行排序時(shí)的案例
Stream對(duì)對(duì)象中的某個(gè)日期屬性進(jìn)行排序
Student對(duì)象
import lombok.Data; import java.util.Date; @Data public class Student { ? ? private String name; ? ? private int age; ? ? private Date birthday; ? ? public Student(String name, int age,Date birthday) { ? ? ? ? this.name = name; ? ? ? ? this.age = age; ? ? ? ? this.birthday = birthday; ? ? } }
List<Student> list = new ArrayList<>(); Student s1 = new Student("a", 11, new Date(2020, 1, 1)); Student s2 = new Student("b", 12, new Date(2020, 1, 2)); Student s3 = new Student("c", 13, new Date(2020, 1, 3)); list.add(s1); list.add(s2); list.add(s3); list = list.stream().sorted(Comparator.comparing(Student::getBirthday)).collect(Collectors.toList());
注意:當(dāng)birthday日期屬性為空時(shí),再使用Comparator.comparing排序會(huì)報(bào)空指針異常,此時(shí)需要指定策略,即當(dāng)日期為空時(shí)排在最前面或排在最后面。
對(duì)日期屬性進(jìn)行排序,并指定日期為空時(shí)的策略
List<Student> list = new ArrayList<>(); Student s1 = new Student("a", 11, new Date(2020, 1, 1)); Student s2 = new Student("b", 12, new Date(2020, 1, 2)); Student s3 = new Student("c", 13, null); list.add(s1); list.add(s2); list.add(s3); list = list.stream().sorted(Comparator.comparing(Student::getBirthday,Comparator.nullsFirst(Comparator.naturalOrder()))).collect(Collectors.toList()); System.out.println(list);
執(zhí)行結(jié)果:
[Student(name=c, age=13, birthday=null), Student(name=a, age=11, birthday=Sun Feb 01 00:00:00 CST 3920), Student(name=b, age=12, birthday=Mon Feb 02 00:00:00 CST 3920)]
排序策略
nullsFirst():為空時(shí)排在最前面
此方法返回比較器,其是空型比較,并認(rèn)為空值小于非空。null首先通過以下邏輯進(jìn)行操作:
- 1.null元素被認(rèn)為小于non-null(即值是null的小于非空的)。
- 2.當(dāng)兩個(gè)元素都為空時(shí),則認(rèn)為它們相等。
- 3.當(dāng)兩個(gè)元素都不為空時(shí),指定的Comparator確定順序。
- 4.如果指定的比較器為null,則返回的比較器將所有非null元素視為相等。
- 5.如果指定的比較器可序列化,則返回的比較器可序列化。
nullsLast():為空時(shí)排在最后面
方法返回比較器,其是空型比較,并認(rèn)為比非空更大空值。null首先通過以下邏輯進(jìn)行操作:
- 1.null元素被認(rèn)為大于非null。
- 2.當(dāng)兩個(gè)元素都為空時(shí),則認(rèn)為它們相等。
- 3.當(dāng)兩個(gè)元素都不為空時(shí),指定的Comparator確定順序。
- 4.如果指定的比較器為null,則返回的比較器將所有非null元素視為相等。
- 5.如果指定的比較器可序列化,則返回的比較器可序列化。
Comparator.naturalOrder 和 Comparator.reverseOrder
很多時(shí)候我們會(huì)面臨這樣的場(chǎng)景,那就是排序邏輯不變,一會(huì)兒根據(jù)升序排序,一會(huì)根據(jù)降序排序,這個(gè)時(shí)候如果我們的Comparable 中的排序邏輯可以滿足上面的排序,就是排序類型(升序還是降序)是不滿足的,這個(gè)時(shí)候我們就可以配合Comparator,來改變?cè)瓉砟J(rèn)的排序類型(其實(shí)就是升序)
nullsFirst與naturalOrder的結(jié)合使用
如下示例:當(dāng)字段為空時(shí)排在最前面,剩下的升序排列
List<Student> list = new ArrayList<>(); Student s1 = new Student("a", 11, new Date(2020, 1, 1)); Student s2 = new Student("b", 12, new Date(2020, 1, 2)); Student s3 = new Student("c", 13, null); list.add(s1); list.add(s2); list.add(s3); list = list.stream().sorted(Comparator.comparing(Student::getBirthday,Comparator.nullsFirst(Comparator.naturalOrder()))).collect(Collectors.toList());
Comparator.nullsFirst(Comparator.naturalOrder()))
- 空值放前面,剩下的升序排序
Comparator.nullsFirst(Comparator.reverseOrder()))
- 空值放前面,剩下的倒敘排序
Comparator.nullsLast(Comparator.naturalOrder()))
- 空值放最后,剩下的升序排序
Comparator.nullsLast(Comparator.reverseOrder()))
- 空值放最后,剩下的倒敘排序
對(duì)象中的多個(gè)屬性進(jìn)行排序
先根據(jù)生日排序,再根據(jù)年齡排序
List<Student> list = new ArrayList<>(); Student s1 = new Student("a", 11, new Date(2020, 1, 1)); Student s2 = new Student("b", 12, new Date(2020, 1, 2)); Student s3 = new Student("c", 13, null); Student s4 = new Student("d", 13, null); list.add(s1); list.add(s2); list.add(s3); list.add(s4); list = list.stream().sorted(Comparator.comparing(Student::getBirthday,Comparator.nullsFirst(Comparator.naturalOrder())).thenComparing(Student::getAge)).collect(Collectors.toList()); System.out.println(list);
字符串日期排序
寫法一
//DateUtil.convertStringToDate為自封裝的一個(gè)String轉(zhuǎn)Date的方法 List<String> maxUpdateTime = updateTimeList.stream().sorted(Comparator.comparing(s -> DateUtil.convertStringToDate(s.toString(),"yyyy-MM-dd HH:mm:ss").getTime()).reversed()).collect(Collectors.toList());
寫法二:
List<String> maxUpdateTime = updateTimeList.stream().sorted(new Comparator<String>() { ?? ?@Override ?? ?public int compare(String o1, String o2) { ?? ??? ?try { ?? ??? ??? ?Date d1 = DateUtil.convertStringToDate(o1, "yyyy-MM-dd HH:mm:ss"); ?? ??? ??? ?Date d2 = DateUtil.convertStringToDate(o2, "yyyy-MM-dd HH:mm:ss"); ?? ??? ??? ?//正序 ? ? ? ? ? ? //return d1.compareTo(d2); ?? ??? ??? ?//倒序 ?? ??? ??? ?return d2.compareTo(d1); ?? ??? ?} catch (Exception e) { ?? ??? ??? ?e.printStackTrace(); ?? ??? ?} ?? ??? ??? ?return 0; ?? ?} }).collect(Collectors.toList());
對(duì)字段進(jìn)行排序,考慮空值的其他寫法
/* 請(qǐng)注意,根據(jù)單屬性name進(jìn)行排序,若需要將name為null的對(duì)象也參與排序,則需要: * .sorted(Comparator.comparing(User::getName, Comparator.nullsLast((o1,o2)->o1.compareTo(o2)))) * 使用方法引用優(yōu)化(注意name的類型是String)即為: * .sorted(Comparator.comparing(User::getName, Comparator.nullsLast(String::compareTo))) */ ? voList = voList.stream().sorted(Comparator.comparing(User::getUserName,Comparator.nullsLast(String::compareTo))) .collect(Collectors.toList());
java stream流排序失效的記錄
strings.parallelStream().filter(s -> s.length() != 2).map(s -> s + "w").sorted((x, y) -> y.length() - x.length()).collect(Collectors.joining(","));
根據(jù)排序結(jié)果來看,不只是順序沒有按照傳入的lambda表達(dá)式來排序,甚至每次排序結(jié)果都是不同的,后發(fā)現(xiàn)這里使用排序的話,就不可以使用并行流來進(jìn)行操作,應(yīng)當(dāng)使用串行流。
如下:
strings.stream().filter(s -> s.length() != 2).map(s -> s + "w").sorted((x, y) -> y.length() - x.length()).collect(Collectors.joining(","));
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring AOP的底層實(shí)現(xiàn)方式-代理模式
這篇文章主要介紹了Spring AOP的底層實(shí)現(xiàn)方式-代理模式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11深入理解MyBatis中的一級(jí)緩存與二級(jí)緩存
這篇文章主要給大家深入的介紹了關(guān)于MyBatis中一級(jí)緩存與二級(jí)緩存的相關(guān)資料,文中詳細(xì)介紹MyBatis中一級(jí)緩存與二級(jí)緩存的工作原理及使用,對(duì)大家具有一定的參考性學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。2017-06-06JAVA中string數(shù)據(jù)類型轉(zhuǎn)換詳解
在JAVA中string是final類,提供字符串不可以修改,string類型在項(xiàng)目中經(jīng)常使用,下面給大家介紹了string七種數(shù)據(jù)類型轉(zhuǎn)換,需要的朋友可以參考下2015-07-07mybatis快速入門學(xué)習(xí)教程新手注意問題小結(jié)
MyBatis 是支持定制化 SQL、存儲(chǔ)過程以及高級(jí)映射的優(yōu)秀的持久層框架。接下來通過本文給大家介紹mybatis快速入門學(xué)習(xí)教程新手注意問題小結(jié),需要的朋友可以參考下2017-02-02SpringBoot?整合?Spring-Session?實(shí)現(xiàn)分布式會(huì)話項(xiàng)目實(shí)戰(zhàn)
本文主要介紹了SpringBoot?整合?Spring-Session?實(shí)現(xiàn)分布式會(huì)話項(xiàng)目實(shí)戰(zhàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07基于JTable的列寬與內(nèi)容自適應(yīng)的實(shí)現(xiàn)方法
本篇文章是對(duì)JTable的列寬與內(nèi)容自適應(yīng)的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05IntelliJ IDEA本地代碼提交到github網(wǎng)站不顯示與本地不同步問題的解決辦法
今天小編就為大家分享一篇關(guān)于IntelliJ IDEA本地代碼提交到github網(wǎng)站不顯示與本地不同步問題的解決辦法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-10-10