首页 > 解决方案 > 如何在处理空指针异常时使用具有多个条件的比较器

问题描述

我不打算使用 lambda,而且我发现很难根据某些条件流式传输和更改名为 status 的属性的值。

testList 有一个 Testdto 类型的元素列表。

MasterDto {
    List<TestDto> testListContent;
}
    
TestDto {
    Long id;
    @NotNull
    LocalDate startDate; /// This is not nullable
    LocalDate endDate; // This is nullable. Hence we have to handle null pointer exceptions.
    String status;
}

最初,所有状态值都是"Inactive"or"Future""Expired"

我想将 ONE 对象的状态值更改"ACTIVE"为当前状态"Inactive"且生效日期最近。

如果有多个对象的生效日期是最近且相等的,我们必须选择 enddate 值较高的对象。(Endate是可以为空的,所以我们这里要避免空指针异常)

如果这些对象的结束日期也相似 OR NULL,我们可以选择列表中的第一个。

这是我到目前为止想出的

masterDtos.gettestListContent()
    .stream()
.max(Comparator.comparing(TestDto::getStartDate)
.thenComparing(
    Comparator.nullsLast(
    Comparator.nullsLast(TestDto::getEndDate)
.get().setStatus(ACTIVE_STATUS);

标签: javalambdajava-streamcomparator

解决方案


原始代码中有几点需要解决:

  1. Comparator::nullsLast应用于另一个比较器,例如Comparator.naturalOrder,而不是方法引用。
  2. 如果找到,应该使用Optional::ifPresent修改列表中相关项目的状态。

因此,代码应如下所示:

public static void activateLastInactive(List<TestDto> data) {
    data.stream()
        .filter(t -> "Inactive".equalsIgnoreCase(t.status))
        .max(
                Comparator.comparing(TestDto::getStartDate)
                          .thenComparing(TestDto::getEndDate, Comparator.nullsLast(Comparator.naturalOrder()))
        )
        .ifPresent(t -> t.setStatus("Active"));
    System.out.println("After: " + data);
}

测试

List<TestDto> data = Arrays.asList(
        new TestDto(1L, LocalDate.of(2021, 1, 1), null, "Active"),
        new TestDto(2L, LocalDate.of(2021, 8, 8), LocalDate.of(2021, 9, 1), "Inactive"),
        new TestDto(3L, LocalDate.of(2021, 8, 8), null, "Inactive"),
        new TestDto(4L, LocalDate.of(2021, 8, 8), null, "Inactive")
) ;

System.out.println("Before: " + data);
activateLastInactive(data);

activateLastInactive(data);

activateLastInactive(data);

输出

Before: [TestDto(id=1, startDate=2021-01-01, endDate=null, status=Active), TestDto(id=2, startDate=2021-08-08, endDate=2021-09-01, status=Inactive), TestDto(id=3, startDate=2021-08-08, endDate=null, status=Inactive), TestDto(id=4, startDate=2021-08-08, endDate=null, status=Inactive)]

After: [TestDto(id=1, startDate=2021-01-01, endDate=null, status=Active), TestDto(id=2, startDate=2021-08-08, endDate=2021-09-01, status=Inactive), TestDto(id=3, startDate=2021-08-08, endDate=null, status=Active), TestDto(id=4, startDate=2021-08-08, endDate=null, status=Inactive)]
// id 3 activated

After: [TestDto(id=1, startDate=2021-01-01, endDate=null, status=Active), TestDto(id=2, startDate=2021-08-08, endDate=2021-09-01, status=Inactive), TestDto(id=3, startDate=2021-08-08, endDate=null, status=Active), TestDto(id=4, startDate=2021-08-08, endDate=null, status=Active)]
// id 4 activated

After: [TestDto(id=1, startDate=2021-01-01, endDate=null, status=Active), TestDto(id=2, startDate=2021-08-08, endDate=2021-09-01, status=Active), TestDto(id=3, startDate=2021-08-08, endDate=null, status=Active), TestDto(id=4, startDate=2021-08-08, endDate=null, status=Active)]
// id 2 activated

推荐阅读