• java8 Stream字段排序sorted()


    Stream的sorted()

    java8中,可以用Stream流的sorted()进行排序。

    示例Bean

    以下我们会使用这个Bean来做示例。

    public class Order {
    
        private String weight;
    
        private Double price;
    
        private String dateStr;
    
        //忽略getter、setter、构造方法、toString
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    原始的排序比较写法

    比较原始的写法,自己手写排序规则。会比较麻烦。

        public void sortByString() {    
            List orderList3 = list.stream().sorted(this::sort).collect(Collectors.toList());
            System.out.println("orderList3:"+orderList3);
        }
    
        public int sort(Order o1, Order o2) {
            if (o1.getDateStr() == null) {
                return 1;
            }
            if (o2.getDateStr() == null) {
                return -1;
            }
            //升序
            return o1.getDateStr().compareTo(o2.getDateStr());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    字段排序

    首先是比较器 Comparator,形式如下:

    Comparator<对象的类名> comparator = Comparator.comparing(对象的类名::get方法名, 升序或降序)
    
    • 1

    排序常用的api:

    naturalOrder()表示自然排序(一般是升序),数字的自然顺序是数字顺序,字符串按字母顺序排序,日期按时间顺序排序。
    reverseOrder()表示 降序。
    nullsLast()表示如果属性为null,就放到最后面。
    nullsFirst()表示如果属性为null,就放到最前面。
    
    • 1
    • 2
    • 3
    • 4
    • 升序如下:
            //naturalOrder()表示自然排序(一般是升序),没有处理属性的null值,排序时可能会空指针
            Comparator comparator1 = Comparator.comparing(Order::getDateStr, Comparator.naturalOrder());
    //        List orderList1 = list.stream().sorted(comparator1).collect(Collectors.toList());
    //        System.out.println("orderList1:"+orderList1);
    
    • 1
    • 2
    • 3
    • 4
    • 降序如下:
            //Comparator.reverseOrder表示 降序,没有处理属性的null值,排序时可能会空指针
            Comparator comparator2 = Comparator.comparing(Order::getDateStr, Comparator.reverseOrder());
    //        List orderList2 = list.stream().sorted(comparator2).collect(Collectors.toList());
    //        System.out.println("orderList2:"+orderList2);
    
    • 1
    • 2
    • 3
    • 4
    • Comparator.nullsLast表示如果属性为null,就放到最后面
            //Comparator.nullsLast表示如果属性为null,就放到最后面
            Comparator comparator3 =  Comparator.comparing(Order::getDateStr, Comparator.nullsLast(naturalOrder()) );
            List orderList3 = list.stream().sorted(comparator3).collect(Collectors.toList());
    //        System.out.println("orderList3:"+orderList3);
    
    • 1
    • 2
    • 3
    • 4
    • Comparator.nullsFirst表示如果属性为null,就放到最前面。
            //Comparator.nullsFirst表示如果属性为null,就放到最前面。
            Comparator comparator4 = Comparator.comparing(Order::getDateStr, Comparator.nullsFirst(Comparator.reverseOrder()));
            List orderList4 = list.stream().sorted(comparator4).collect(Collectors.toList());
    //        System.out.println("orderList4:"+ orderList4);
    
    • 1
    • 2
    • 3
    • 4

    java8多字段排序

    有时我们还需要对多个字段进行排序。
    多个字段排序,先对第一个排序字段排序,当第一个排序字段相同时,会使用第二个排序字段进行排序。

    多字段排序的api

    • 多个字段排序的格式
    Comparator<对象的类名> comparator = Comparator.comparing(对象的类名::方法名1, 升序或降序)
    		.thenComparing(Comparator.comparing(对象的类名::方法名2, 升序或降序));
    
    • 1
    • 2

    如果是三个以上的字段排序,就继续用 thenComparing 连接。

    示例如下:

            //先按第一个字段降序,再按第二个字段降序,如果属性为null,就放到最后面。
            Comparator comparator5 = Comparator.comparing(Order::getDateStr, Comparator.nullsLast(Comparator.reverseOrder()))
                    .thenComparing(Order::getPrice, Comparator.nullsLast(Comparator.reverseOrder()));
            List orderList5 = list.parallelStream().sorted(comparator5).collect(Collectors.toList());
            System.out.println("orderList5:"+ orderList5);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    reversed()和Comparator.reverseOrder()的区别:

    Comparator.comparing(对象的类名::属性的方法名).reversed();
    Comparator.comparing(对象的类名::属性的方法名,Comparator.reverseOrder());
    
    • 1
    • 2

    reversed()是得到排序结果后再反转,
    Comparator.reverseOrder()是对属性按照降序进行排序,
    reversed()在多字段排序时,很容易混乱,不建议使用。
    Comparator.reverseOrder()更好理解,也更好用些。

    代码如下:

    public class SortedDemo {
    
        /**
         * naturalOrder()表示自然排序(一般是升序),
         * Comparator.reverseOrder()表示 降序。
         *
         * nullsLast()表示如果属性为null,就放到最后面。
         * nullsFirst()表示如果属性为null,就放到最前面。
         *
         */
        public static void order() {
            //设置 order对象属性,以下是lombok的写法,相当于 setter
            Order order1=Order.builder().dateStr("2021-10-01 00:00:00").price(33.3).build();
            Order order2=Order.builder().dateStr("2021-10-01 00:00:00").price(1.3).build();
            Order order3=Order.builder().dateStr("2021-10-01 00:00:00").price(55.3).build();
            Order order4=Order.builder().dateStr("2021-12-01 00:00:00").price(55.3).build();
            //添加null测试
            Order order5=Order.builder().dateStr(null).price(null).build();
    
            List list= new ArrayList<>();
            list.add(order1);
            list.add(order2);
            list.add(order3);
            list.add(order4);
            list.add(order5);
    
            // ==========================================================================
            //naturalOrder()表示自然排序(一般是升序),没有处理null,排序时可能会空指针
            Comparator comparator1 = Comparator.comparing(Order::getDateStr, Comparator.naturalOrder());
    //        List orderList1 = list.stream().sorted(comparator1).collect(Collectors.toList());
    //        System.out.println("orderList1:"+orderList1);
    
    
            // ==========================================================================
            //Comparator.reverseOrder表示 降序,没有处理null,排序时可能会空指针
            Comparator comparator2 = Comparator.comparing(Order::getDateStr, Comparator.reverseOrder());
    //        List orderList2 = list.stream().sorted(comparator2).collect(Collectors.toList());
    //        System.out.println("orderList2:"+orderList2);
    
            // ==========================================================================
    
            //Comparator.nullsLast表示如果属性为null,就放到最后面
            Comparator comparator3 =  Comparator.comparing(Order::getDateStr, Comparator.nullsLast(naturalOrder()) );
            List orderList3 = list.stream().sorted(comparator3).collect(Collectors.toList());
    //        System.out.println("orderList3:"+orderList3);
    
            // ==========================================================================
    
            //nullsFirst表示如果属性为null,就放到最前面。
            Comparator comparator4 = Comparator.comparing(Order::getDateStr, Comparator.nullsFirst(Comparator.reverseOrder()));
            List orderList4 = list.stream().sorted(comparator4).collect(Collectors.toList());
    //        System.out.println("orderList4:"+ orderList4);
    
            // ==========================================================================
    
            //先按第一个字段降序,再按第二个字段降序,如果属性为null,就放到最后面。
            //输出: [Order(price=55.3, dateStr=2021-12-01 00:00:00),
            //Order( price=55.3, dateStr=2021-10-01 00:00:00),
            //Order(price=33.3, dateStr=2021-10-01 00:00:00),
            //Order(price=1.3, dateStr=2021-10-01 00:00:00)]
    
            Comparator comparator5 = Comparator.comparing(Order::getDateStr, Comparator.nullsLast(Comparator.reverseOrder()))
                    .thenComparing(Order::getPrice, Comparator.nullsLast(Comparator.reverseOrder()));
            List orderList5 = list.parallelStream().sorted(comparator5).collect(Collectors.toList());
            System.out.println("orderList5:"+ orderList5);
    
    
        }
    
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    Stream资料

    https://www.cnblogs.com/expiator/p/12297003.html

  • 相关阅读:
    python并发编程 多线程/多进程/协程
    K_A02_005 基于单片机驱动数码管 LED 按键模块(TM1638) 流水灯 0-7 按键值显示
    C++设计模式学习-面向对象设计原则
    Elasticsearch性能优化实践
    智慧机场航线监测系统:提升航空运输安全与效率的新一步
    selector xmlns:android=“http://schemas.android.com/apk/res/android
    Azure Terraform(十三)提升 Azure Web App Plan 的性能
    mysql不区分大小写配置
    1、基本概念
    Oracle JDK 和 OpenJDK 有什么区别?
  • 原文地址:https://blog.csdn.net/sinat_32502451/article/details/133001980