Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to understand this Java 8 Stream collect() method?

I was trying to convert an int array to List and I took the unfamiliar route of using Java 8 Stream and came up with this

Arrays.stream(arr).boxed().collect(Collectors.toList());

I still have difficulty fully understand this line, mostly,

  1. Why is Collectors.toList() in this case returns an ArrayList<Integer> implementing List interface? Why not LinkedList<Integer> or any other generic class conforming to List interface? I can't find anything about this, except for a brief mentioning of ArrayList here, in the API Notes section.

  2. What does the left panel of enter image description here Stream.collect() mean? Obviously R is the generic return type (ArrayList<Integer> in my code here). And I think <R, A> is the generic type argument of the method, but how are they specified? I looked into Collector interface doc and was not able to absorb it.

like image 344
user3207158 Avatar asked Nov 04 '19 06:11

user3207158


People also ask

What does collect do in Java streams?

Java Stream collect() is mostly used to collect the stream elements to a collection. It's a terminal operation. It takes care of synchronization when used with a parallel stream. The Collectors class provides a lot of Collector implementation to help us out.

What is collect method in Stream API?

collect() Method. Stream. collect() is one of the Java 8's Stream API's terminal methods. It allows us to perform mutable fold operations (repackaging elements to some data structures and applying some additional logic, concatenating them, etc.) on data elements held in a Stream instance.

How do I read a Stream in Java?

Java InputStream read InputStream reads bytes with the following read methods : read(byte[] b) — reads up to b. length bytes of data from this input stream into an array of bytes. read(byte[] b, int off, int len) — reads up to len bytes of data from this input stream into an array of bytes.

How many methods are there in the collection interface for generating a Stream in Java 8?

With Java 8, Collection interface has two methods to generate a Stream.


2 Answers

  1. It's a default implementation. ArrayList is used, because it's best in most use cases, but if it's not suitable for you, you can always define your own collector and provide factory for Collection you wish:

    Arrays.stream(arr).boxed().collect(toCollection(LinkedList::new));
    
  2. Yes, A and R are generic parameters of this method, R is the return type, T is the input type and A is an intermediate type, that appears in the whole process of collecting elements (might not be visible and does not concern this function). The beginning of Collector's javadoc defines those types (they are consistent across the entire doc):

    T - the type of input elements to the reduction operation
    A - the mutable accumulation type of the reduction operation (often hidden as an implementation detail)
    R - the result type of the reduction operation

like image 158
Andronicus Avatar answered Sep 29 '22 18:09

Andronicus


  1. Why is Collectors.toList() in this case returns an ArrayList implementing List interface?

As the method definition suggests it returns a Collector implementation with collector supplier as ArrayList. Hence, it's very clear from method definition below that Collectors.toList always returns ArrayList collector(While it's arguable why toList not toArrayList word is used in method name).

public static <T>
    Collector<T, ?, List<T>> toList() {
        return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
                                   (left, right) -> { left.addAll(right); return left; },
                                   CH_ID);
    }
  1. What does the left panel of <R, A> R collect(Collector<? super T, A, R> collector) means

If you refer to documentation comments it accurately mentions what these generic types are:

/*
      @param <R> the type of the result
      @param <A> the intermediate accumulation type of the {@code Collector}
      @param collector the {@code Collector} describing the reduction
      @return the result of the reduction
*/
 <R, A> R collect(Collector<? super T, A, R> collector);
like image 26
Vinay Prajapati Avatar answered Sep 29 '22 18:09

Vinay Prajapati