给定以下类Test
class Test {
String testName;
String studName;
String status;
}以及一系列的测试
List<Test> tests = List.of(
new Test("English", "John", "passed"),
new Test("English", "Dave", "passed"),
new Test("Science", "Alex", "failed"),
new Test("Science", "Jane", "failed"),
new Test("History", "Dave", "passed"),
new Test("Mathematics", "Anna", "passed"),
new Test("Mathematics", "Lisa", "passed"),
new Test("Mathematics", "Paul", "failed"),
new Test("Geography", "Mark", "passed"),
new Test("Physics", "John", "failed"));我需要按testName进行分组,只计算,其中status等于"passed"。我需要在流中执行以下代码:
Map<String, Long> result2 = new HashMap<>();
for (Test t : tests) {
result2.putIfAbsent(t.getTestName(), 0L);
if (t.getStatus().equals("passed")) {
result2.computeIfPresent(t.getTestName(), (k, v) -> v + 1);
}
}正确和期望的输出:
{Geography=1, English=2, Science=0, Mathematics=2, History=1, Physics=0}我正在寻找一种流的方法,但还没有找到解决方案。一个简单的Collectors.counting将计算所有数据,而不考虑“失败/传递”状态:
Map<String, Long> resultCounting = tests.stream()
.collect(Collectors.groupingBy(
Test::getTestName,
Collectors.counting()
));输出:
{Geography=1, English=2, Science=2, Mathematics=3, History=1, Physics=1}我考虑过事先过滤,但之后我会放松那些所有状态都是"failed"的主题。
Map<String, Long> resultFilter = tests.stream()
.filter(t -> t.getStatus().equals("passed"))
.collect(Collectors.groupingBy(
Test::getTestName,
Collectors.counting()
));输出:
{Geography=1, English=2, Mathematics=2, History=1}如何将所有测试按testName分组,但只计算状态为"passed"的测试?
是否有可能在某种条件下包装Collectors.counting()?
发布于 2022-08-03 00:00:50
您可以使用收集器toMap(keyMapper,valueMapper,mergeFunction)实现所需的结果。
valueMapper函数将产生1或0,这取决于status。
Map<String, Integer> passCountByTestName = tests.stream()
.collect(Collectors.toMap(
Test::getTestName,
test -> test.getStatus().equals("passed") ? 1 : 0,
Integer::sum
));
passCountByTestName.forEach((k, v) -> System.out.println(k + " -> " + v));输出:
Geography -> 1
English -> 2
Science -> 0
Mathematics -> 2
History -> 1
Physics -> 0Sidenote:最好使用boolean或枚举作为status属性的类型,而不是依赖字符串值。
https://stackoverflow.com/questions/73214787
复制相似问题