开发者

java之使用stream对日期排序方式

目录
  • Java使用stream对日期排序
    • Stream对对象中的某个日期属性进行排序
    • 对日期属性进行排序,并指定日期为空时的策略
    • 排序策略
    • 对象中的多个属性进行排序
    • 字符串日期排序
    • 对字段进行排序,考虑空值的其他写法
  • java stream流排序失效的记录
    • 总结

      java使用stream对日期排序

      主要讲解Stream对日期字段进行排序时的写法,以及当日python期字段为null时的排序策略。或者对多个属性进行排序时的案例

      Stream对对象中的某个日期属性进行排序

      Student对象

      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 Stpythonudent("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());

      注意:当birthday日期属性为空时,再使用Comparator.comparing排序会报空指针异常,此时需要指定策略,即当日期为空时排在最前面或排在最后面。

      对日期属性进行排序,并指定日期为空时的策略

      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);

      执行结果:

      [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():为空时排在最前面

      此方法返回比较器,其是空型比较,并认为空值小于非空。null首先通过以下逻辑进行操作:

      • 1.null元素被认为小于non-null(即值是null的小于非空的)。
      • 2.当两个元素都为空时,则认为它们相等。
      • 3.当两个元素都不为空时,指定的Comparator确定顺序。
      • 4.如果指定的比较器为null,则返回的比较器将所有非null元素视为相等。
      • 5.如果指定的比较器可序列化,则返回的比较器可序列化。

      nullsLast():为空时排在最后面

      方法返回比较器,其是空型比较,并认为比非空更大空值。null首先通过以下逻辑进行操作:

      • 1.null元素被认为大于非null。
      • 2.当两个元素都为空时,则认为它们相等。
      • 3.当两个元素都不为空时,指定的Comparator确定顺序。
      • 4.如果指定的比较器为null,则返回的比较器将所有非null元素视为相等。
      • 5.如果指定的比较器可序列化,则返回的比较器可序列化。

      Comparator.naturalOrder 和 Comparator.reverseorder

      很多时候我们会面临这样的场景,那就是排序逻辑不变,一会儿根据升序排序,一会根据降序排序,这个时候如果我们的Comparable 中的排序逻辑可以满足上面的排序,就是排序类型(升序还是降序)是不满足的,这个时候我们就可以配合Comparator,来改变原来默认的排序类型(其实就是升序)

      nullsFirst与naturalOrder的结合使用

      如下示例:当字段为空时排在最前面,剩下的升序排列

      List<Student> list = new ArrayList<>();
      Student s1 = new Student("a", 11, new Date(202开发者_JS开发0, 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()))
      • 空值放最后,剩下的倒叙排序

      对象中的多个属性进行排序

      先根据生日排序,再根据年龄排序

      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为自封装的一个String转Date的方法
      List<String> maxUpdateTime = updateTimeList.swww.devze.comtream().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");
        python 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());

      对字段进行排序,考虑空值的其他写法

      /* 请注意,根据单属性name进行排序,若需要将name为null的对象也参与排序,则需要:
      * .sorted(Comparator.comparing(User::getName, Comparator.nullsLast((o1,o2)->o1.compareTo(o2))))
      * 使用方法引用优化(注意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(","));

      根据排序结果来看,不只是顺序没有按照传入的lambda表达式来排序,甚至每次排序结果都是不同的,后发现这里使用排序的话,就不可以使用并行流来进行操作,应当使用串行流。

      如下:

      strings.stream().filter(s -> s.length() != 2).map(s -> s + "w").sorted((x, y) -> y.length() - x.length()).collect(Collectors.joining("python,"));

      总结

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

      0

      上一篇:

      下一篇:

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      最新开发

      开发排行榜