Home > Software design >  Java stream again over a collection which was collected using Stream Collector of
Java stream again over a collection which was collected using Stream Collector of

Time:09-10

I have a similar use case to this stack overflow question and was trying to use it without storing the result in a List<List<String>> but instead call stream() on it.

I have a strange compile time error if I don't assign it to List<List<String>> because of type mismatch. To reproduce just comment out the assignment to output. The question is why is this a compile error?

public static void main(String args[]) {
    List<String> input = Arrays.asList("RED", "RED", "BLUE", "BLUE", "BLUE", "BLUE", "RED", "RED");
    List<List<String>> output =  // if this line commented it doesn't compile
            input.stream()
                 .collect(Collector.of(ArrayList::new, (accumulator, item) ->
                 {
                     if (accumulator.isEmpty()) {
                         List<String> list = new ArrayList<>();
                         list.add(item);
                         accumulator.add(list);
                     } else {
                         List<String> last = accumulator.get(accumulator.size() - 1);
                         if (last.isEmpty() || last.get(0).equals(item)) {
                             last.add(item);
                         } else {
                             List<String> list = new ArrayList<>();
                             list.add(item);
                             accumulator.add(list);
                         }
                     }
                 }, (left, right) -> {
                     left.addAll(right);
                     return left;
                 }));
}

my idea was to use it like

input.stream().collect(Collector.of(.....)).stream().(and do something else)

CodePudding user response:

Functions in Java have no type by itself. They are poly expressions. It means their type should be inferred from the context. It applies for all arguments of the Collector.of().

List<List<String>> output - provides the target type, without it, type inference mechanism has no clue what type of object your Collector is expected to produce.

To make the code compile you can use the type-witness while calling Collector.<all the types of functions used in collector here>of().

The simplest way to make this stream-statement compile is to provide explicit types of arguments of the accumulator:

(List<List<String>> accumulator, String item) ->
     {
          ...
     },
  • Related