我有一个包含多个属性的对象列表,其中一个是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);
答案 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
将此日期与另一个日期进行比较。 比较主要基于 日期从最早到最晚。它是“等于” 由
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类,而不是从流中返回一个选项。
感谢大家的帮助,希望这个答案对其他人有帮助。