can return java stream groupingby to this's array variable?

Viewed 130

Q.1) hi, java stream's groupingby can make oneself's array varible?

this is entity

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

this is test List sample

{
   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)
}

And i want group by test.id, for example

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

what should i do?

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

Q.2) how can i merge bellow two stream codes?

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

about this..?

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

Q3) above Q1, Q2's stream codes are better performance than java 'for' syntax?

Thank you in advance. :)

2 Answers

For grouping assuming a constructor like Test(int id, int itemId, int[] itemIds) and fluent getters such as id(), itemId() and itemIds() you could unflatten your data this way:

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());

As for merging your filter & throwing logic within a single statement I can't really think of any other way than peek such as:

List<Test> unflattenedTests = tests.stream()
   .peek(t -> { if (t.isFilter()) throw new RuntimeException(); })
   .collect(...

@plalx thanks for answer!

Thanks to answer, this is my solution

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();
        }
    };

what do you think, my solution. i worry about low performance.

Anyway, my knowledge has been upgraded! thanks a lot. :)

Related