It is possible to neglect some elements during Collectors.groupingBy
or Collectors.partitioningBy
?
Of course I know I can place a .filter()
anywhere in a stream. But my problem is that I have to run a rather complex and expensive evaluation, to decide in which "group" my objects should be divided into.
Moreover, there are always many objects that I would want to neglect during collecting.
Example: imagine a List<Foo>
, that I want to split into 2 lists. That's easy, but how can I additionally neglect all objects that don't fit into my evaluated condition?
var map = foos.stream().collect(Collectors.groupingBy(
foo -> {
int bar = complexEvaluation(foo);
if (bar > 1000) return true;
if (bar < 0) return false;
//TODO how to neglect the rest between 0-1000
},
Collectors.mapping(foo -> foo.id, Collectors.toSet())
));
Just use an enum
to define your 3 cases:
enum Categories {
HIGH, LOW, NEGATIVE
}
var map = foos.stream().collect(Collectors.groupingBy(
foo -> {
int bar = complexEvaluation(foo);
if (bar > 1000) return HIGH;
if (bar < 0) return NEGATIVE;
return LOW;
},
Collectors.mapping(foo -> foo.id, Collectors.toSet())
));
Then ignore or remove LOW
if you don’t need it. It also has the added benefits of giving more meaning to your categories instead of just naming them true
/false
, and making it easier to refactor if you need more categories in the future.
Only drawback is that it builds a useless LOW
set, but that’s only an issue if it is really big compared to the other sets and the complexEvaluation()
operation.