记录一下对集合排序,处理属性为空且参与排序方法

1 篇文章 0 订阅
1 篇文章 0 订阅

一、需求

实际项目中经常存在对集合某个或多个属性进行排序,例如根据姓名排序,根据金额排序;或者多个字段排序,例如姓名首字母升序+金额降序两个字段排序等等。
但是有时候姓名或金额会为空,之前我们排序的时候需要拿出这些属性做判空处理,然后再排序,不然会报错。今天这个方法不用自己处理空字段判读了,并且值为空也参与排序。

二、了解Comparator.nullsFirst和Comparator.nullsLast

1、Comparator.nullsFirst

  • 空元素被认为小于非空元素。
  • 当两个元素都是空的时候,那么它们被认为是相等的。
  • 当两个元素都是非空的时候,指定的比较器决定了顺序。
  • 如果指定的比较器是空的,那么返回的比较器认为所有非空的元素是相等的。

2、Comparator.nullsLast

  • 空元素被认为是大于非空元素的。
  • 当两个元素都是空的时候,那么它们被认为是相等的。
  • 当两个元素都是非空的时候,指定的比较器决定了顺序。
  • 如果指定的比较器是空的,那么返回的比较器认为所有非空的元素是相等的。

三、了解Comparator.naturalOrder和Comparator.reverseOrder

1、Comparator.naturalOrder

  • 自然排序,升序

2、Comparator.reverseOrder

  • 扭转自然排序,降序

四、定义实体类

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.math.BigDecimal;

/**
 * @Author:
 * @Description
 * @Date: 下午2:09 2024/1/23
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SortEmpty implements Serializable {

    /**
     * 姓名
     */
    private String name;
    /**
     * 年龄
     */
    private Integer age;
    /**
     * 奖学金
     */
    private BigDecimal amount;

}

五、测试排序

import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author:
 * @Description
 * @Date: 下午2:10 2024/1/23
 */
@Slf4j
public class SortTest {

    /**
     * 单个字段排序
     */
    public static void oneFiledSort() {
        //mock 数据
        List<SortEmpty> list = getData();
        //根据奖学金降序排序,并且奖学金为空的放到最后
        List<SortEmpty> amountSort = list.stream().sorted(Comparator.comparing(SortEmpty::getAmount, Comparator.nullsFirst(BigDecimal::compareTo)).reversed()).collect(Collectors.toList());
        log.info("************amountSort根据奖学金降序排序,并且奖学金为空的放到最后,排序后结果如下");
        amountSort.forEach(e -> log.info("" + e));
        //根据姓名升序排序,并且名字为空的放到最后
        List<SortEmpty> nameSort = list.stream().sorted(Comparator.comparing(SortEmpty::getName, Comparator.nullsLast(String::compareTo))).collect(Collectors.toList());
        log.info("************根据姓名升序排序,并且名字为空的放到最后,排序后结果如下");
        nameSort.forEach(e -> log.info("" + e));
    }

    /**
     * 多个字段排序
     * 根据姓名首字母升序,奖学金降序
     */
    public static void manyFiledSort() {
        //mock 数据
        List<SortEmpty> list = getData();
        //  多字段排序规则
        Comparator<SortEmpty> comparator5 = Comparator.comparing(SortEmpty::getName, Comparator.nullsLast(Comparator.naturalOrder()))
                .thenComparing(SortEmpty::getAmount, Comparator.nullsLast(Comparator.reverseOrder()));
        List<SortEmpty> orderList = list.parallelStream().sorted(comparator5).collect(Collectors.toList());
        log.info("************多个字段排序,根据姓名首字母升序,奖学金降序结果如下");
        orderList.forEach(e -> log.info("" + e));
    }

    /**
     * mock 数据
     *
     * @param
     */
    public static List<SortEmpty> getData() {
        List<SortEmpty> list = new ArrayList<>();
        list.add(new SortEmpty("abc", 11, null));
        list.add(new SortEmpty("gbc", 112, BigDecimal.valueOf(50)));
        list.add(new SortEmpty(null, 13, BigDecimal.valueOf(1000)));
        list.add(new SortEmpty("lbc", 119, null));
        list.add(new SortEmpty("lbc", 119, BigDecimal.valueOf(300)));
        list.add(new SortEmpty("lbc", 119, BigDecimal.valueOf(600)));
        return list;
    }

    /**
     * 测试
     *
     * @param args
     */
    public static void main(String[] args) {
        oneFiledSort();
        manyFiledSort();
    }
}

六、结果

在这里插入图片描述

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值