使用Java 8流在LocalDate属性的对象列表中查找最新日期

时间:2018-12-11 15:40:58

标签: java-8 java-stream localdate

我有一个包含多个属性的对象列表,其中一个是LocalDate。我想从列表中找到日期最近的对象。

我对Java 8和使用流非常满意。像大多数编程一样,似乎有多种方法可以为这只猫换皮。这就是我到目前为止所拥有的。

list.stream().filter( object -> object.getId() == id
&& object.getCancelDate() == null 
&& object.getEarliestDate() != null)
.min( Comparator.comparing( LocalDate::toEpochDay )
.get();

这为我提供了Comparator函数的“无法从静态上下文引用非静态方法”。

我已经考虑过可能还创建一个仅包含过滤对象的日期的地图,到目前为止,我们已经提出了类似的建议。

list.stream().filter( object -> object.getId() == id
&& object.getCancelDate() == null 
&& object.getEarliestDate() != null)
.map( data -> data.getEarliestDate() )
.collect( Collectors.toList() )

,我不确定从那里到哪里去,甚至还行不通。

我知道有一个简单的方法可以做到这一点,但是我的大脑只是没有连接点。

更新

感谢您的回复。我更新了我的代码      Optional<YourObject> recentObject = list.stream().filter(object -> object.getId() == id && object.getCancelDate() == null && object.getEarliestDate() != null) .max(Comparator.comparing(s -> s.getEarliestDate().toEpochDay()));

我现在收到编译器错误 类型不兼容。

Required:Optional<MyClass>
Found:Optional<capture<? extends MyClass>>

该方法确实扩展了MyClass,因此在Optional的类型声明中,我是否需要做类似MyClass.class的操作?

更新2 感谢@Hogen通过在末尾添加.map()来帮助修复编译器错误。更改后的外观如下。

Optional<MyClass> date = 
list.stream().filter(object -> object.getId() == id &&
object.getCancelDate() == null &&
object.getEarliestDate() != null)
.max(Comparator.comparing( s -> s.getEarliestDate()
.toEpochDay())).map(Function.identity());

但是,在获得一些帮助之后,我能够提出一个解决方案,将地图移至其他位置,这样就不会遇到使用扩展类的问题。

Optional<LocalDate> mostRecentDate = list.stream()
.filter(data -> data.getId() == id && data.getCancelDate() == null)
.map(MyObject::getEarliestDate)
.filter(Objects::nonNull)
.max(LocalDate::compareTo);

2 个答案:

答案 0 :(得分:4)

您主要在寻找:

Optional<YourObject> recentObject = list.stream()
        .filter(object -> object.getId() == id && object.getCancelDate() == null && object.getEarliestDate() != null)
        .max(Comparator.comparing(YourObject::getEarliestDate)); // max of the date for recency

来自LocalDate.compareTo

  

将此日期与另一个日期进行比较。   比较主要基于   日期从最早到最晚。它是“等于”   由Comparable定义。

答案 1 :(得分:1)

将此内容放入可见性答案中。根据@nullpointer的回答和@Holger的建议,我能够提出以下两种解决方案。

解决方案1 ​​

Optional<MyClass> mostRecentDate = list.stream()
    .filter(myObject -> myObject.getId() == id &&
     myObject.getCancelDate() == null && myObject.getEarliestDate() != null)
    .max(Comparator.comparing( s -> s.getEarliestDate()
    .toEpochDay())).map(Function.identity());

解决方案2

LocalDate mostRecentDate = list.stream()
    .filter(myObject -> myObject.getId() == id && myObject.getCancelDate() == null)
    .map(MyObject::getEarliestDate)
    .filter(Objects::nonNull)
    .max(LocalDate::compareTo)
    .orElse(null);

这两种解决方案都可以,但是第二种解决方案在我看来更干净而且不那么含糊。它将删除实际上并未执行任何操作的.map(Function.identity())代码,正如@Holgen在使用Java 8的新Method Reference ::时指出的那样。它还过滤对象列表,并将日期映射到新列表,然后使用带有compareTo()方法的.max()而不是自定义函数。我认为自定义函数和无用的代码是凌乱的,对于任何阅读该代码的人来说,可能会使它变得更难以理解。

请注意,在第二个解决方案中,我还删除了Optional类。使用.orElse()可以返回实际的LocalDate类,而不是从流中返回一个选项。

感谢大家的帮助,希望这个答案对其他人有帮助。