(抱歉,如果“括号”一词令人困惑,我将其取自荷兰语翻译的“税括号”)。
如何根据属性阈值将项目收集到组以及前面的每个组中?
示例:
Loan A, duration of 6 months
Loan B, duration of 10 months
Loan C, duration of 12 months
结果为Map<Integer, List<Loan>>
:
6 -> {A, B, C}
10 -> {B, C}
12 -> {C}
目前我正在使用 LinkedHashMap 路线,然后从流中收集项目后,遍历所有组来更新它们:
Map<Integer, List<Loan>> loansByDuration = loans.stream()
.collect(groupingBy(Loan::getDuration, LinkedHashMap::new, toList()));
List<Loan> previousGroup = null;
for (List<Loan> currentGroup : loansByDuration.values()) {
if (previousGroup != null) {
currentGroup.addAll(previousGroup);
}
previousGroup = currentGroup;
}
所以我正在做的是 map 中的每个后续列表值都将包含所有先前的贷款以及仅与相应期限键相关的贷款。与累计小计类似。
这可以通过标准 API 或其他类似自定义收集器的方式来完成吗?
最佳答案
对于用例来说,是否有必要使用像 Map<Integer, List<Loan>>
这样的类型?因此,每个列表都会包含所有以前的贷款。这意味着对 Loan
会有多余的引用。 .
或者是提供关于 loans
的 View 的用例分组依据 duration
?
在这种情况下,我们可以使用另一种方法:使用 Stream
查看贷款(基于Java 9+)。
public class Loans {
private final List<Loan> loans;
public Loans(List<Loan> loans) {
this.loans = loans.stream()
.sorted(Comparator.comparingInt(Loan::getDuration))
.collect(Collectors.toList());
}
public Stream<Loan> getUpTo(int duration) {
return loans.stream().takeWhile(l -> l.getDuration() <= duration);
}
}
因为我们有 List<Loan>
排序方式 duration
我们可以使用Stream.takeWhile
获得 Stream
所需的Loan
s 为某个 duration
.
这可以工作,例如像这样:
Loans loans = new Loans(List.of(new Loan("A", 6), new Loan("B", 10), new Loan("C", 12));
loans.getUpTo(1); // <empty>
loans.getUpTo(5); // <empty>
loans.getUpTo(6); // Loan("A", 6)
loans.getUpTo(10); // Loan("A", 6), new Loan("B", 10)
loans.getUpTo(11); // Loan("A", 6), new Loan("B", 10)
loans.getUpTo(12); // Loan("A", 6), new Loan("B", 10), Loan("C", 12)
loans.getUpTo(100); // Loan("A", 6), new Loan("B", 10), Loan("C", 12)
万一 List<Loan>
应该需要的话,我们还可以collect
流式元素 toList()
.
关于java - 将项目收集到括号中(当前组和所有先前组),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52832134/