[英]Java 8 Streams reduce remove duplicates keeping the most recent entry
我有一個Java bean,例如
class EmployeeContract {
Long id;
Date date;
getter/setter
}
如果其中有很長的列表,其中我們有ID重復但日期不同的重復項,例如:
1, 2015/07/07
1, 2018/07/08
2, 2015/07/08
2, 2018/07/09
如何減少這樣的列表,使其僅保留具有最新日期的條目,例如:
1, 2018/07/08
2, 2018/07/09
? 最好使用Java 8 ...
我從類似以下內容開始:
contract.stream()
.collect(Collectors.groupingBy(EmployeeContract::getId, Collectors.mapping(EmployeeContract::getId, Collectors.toList())))
.entrySet().stream().findFirst();
這使我可以在各個組中進行映射,但是我對如何將其收集到結果列表中感到困惑-恐怕我的流不太強...
好吧,我將在這里以回答的形式發表我的評論:
yourList.stream()
.collect(Collectors.toMap(
EmployeeContract::getId,
Function.identity(),
BinaryOperator.maxBy(Comparator.comparing(EmployeeContract::getDate)))
)
.values();
如果您真的很在意這會給您一個Collection
而不是一個List
。
您可以按照以下兩個步驟進行操作:
List<EmployeeContract> finalContract = contract.stream() // Stream<EmployeeContract>
.collect(Collectors.toMap(EmployeeContract::getId,
EmployeeContract::getDate, (a, b) -> a.after(b) ? a : b)) // Map<Long, Date> (Step 1)
.entrySet().stream() // Stream<Entry<Long, Date>>
.map(a -> new EmployeeContract(a.getKey(), a.getValue())) // Stream<EmployeeContract>
.collect(Collectors.toList()); // Step 2
第一步 :確保將date
s與映射到id
的date
進行比較。
第二步 :將這些鍵值對映射到最終的List<EmployeeContract>
。
使用vavr.io,您可以這樣操作:
var finalContract = Stream.ofAll(contract) //create io.vavr.collection.Stream
.groupBy(EmployeeContract::getId)
.map(tuple -> tuple._2.maxBy(EmployeeContract::getDate))
.collect(Collectors.toList()); //result is list from java.util package
您只想補充現有的答案,就可以:
如何將其收集到結果列表中
以下是一些選項:
將values()
包裝到ArrayList
:
List<EmployeeContract> list1 = new ArrayList<>(list.stream() .collect(toMap(EmployeeContract::getId, identity(), maxBy(comparing(EmployeeContract::getDate)))) .values());
將toMap
收集器包裝到collectingAndThen
:
List<EmployeeContract> list2 = list.stream() .collect(collectingAndThen(toMap(EmployeeContract::getId, identity(), maxBy(comparing(EmployeeContract::getDate))), c -> new ArrayList<>(c.values())));
使用另一個流將values
收集到新的List
中:
List<EmployeeContract> list3 = list.stream() .collect(toMap(EmployeeContract::getId, identity(), maxBy(comparing(EmployeeContract::getDate)))) .values() .stream() .collect(toList());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.