2

Q.1)你好,java流的groupingby可以使自己的数组变数吗?

这是实体

public class Test {
   private int id;
   private int itemId;
   private int[] itemIds;
   private boolean filter;
}

这是测试列表样本

{
   test(id=1, itemId=1)
   test(id=1, itemId=2)
   test(id=1, itemId=3)
   test(id=2, itemId=5)
   test(id=2, itemId=11)
}

我想按 test.id 分组,例如

{
   test(id=1, itemIds=[1,2,3])
   test(id=2, itemIds=[5,11])
}

我该怎么办?

tests.stream().collect(Collectors.groupingBy(Test::getId), ?, ?);

Q.2) 我如何合并下面的两个流代码?

tests.stream().filter(Test::isFilter).anyMatch(t -> {throw new Exception;});
tests.stream().collect(Collectors.groupingBy(Test::getId, ?, ?); // Q1 result

对这个..?

tests.stream().filter(Test::isFilter).anyMatch(t -> {throw new Exception;}).collect(Collectors.groupingBy(Test::getId, ?, ?);

Q3) Q1、Q2 的流代码比 java 'for' 语法性能更好?

先感谢您。:)

4

2 回答 2

1

对于假设构造函数和流畅的 getter 进行分组,Test(int id, int itemId, int[] itemIds)id()可以通过这种方式展开数据:itemId()itemIds()

List<Test> unflattenedTests = tests.stream()
   .collect(Collectors.groupingBy(Test::id))
   .entrySet().stream().map(e -> new Test(
       e.getKey().intValue(),
       0,
       e.getValue().stream().mapToInt(Test::itemId).toArray()
    ))
    .collect(Collectors.toList());

至于在单个语句中合并您的过滤器和抛出逻辑,我真的想不出任何其他方式,peek例如:

List<Test> unflattenedTests = tests.stream()
   .peek(t -> { if (t.isFilter()) throw new RuntimeException(); })
   .collect(...
于 2021-07-09T03:30:07.710 回答
0

@plalx感谢您的回答!

感谢回答,这是我的解决方案

tests.stream()
    .peek(t -> {if (Test::isFilter) throw new Exception();})
    .collect(Collectors.groupingBy(Test::getId, Collectors.mapping(Test::getItemId, Collectors.toSet())))
    .forEach((id, itemIdSet) -> {
        if (!somBusiness(id, itemIdSet)) {
            throw new Exception();
        }
    };

你怎么看,我的解决方案。我担心性能低下。

无论如何,我的知识已经升级了!多谢。:)

于 2021-07-09T07:19:54.467 回答