Adit A. Pillai
Adit A. Pillai

Reputation: 667

Implementation of Collection.stream()

I have been working on JDK 1.8 for a few days now where I came across some piece of code which was similar to this:

List<Integer> list = Arrays.asList(1,2,3,4,5);
list.stream();

Now, easy and clean as it may appear to the people who have been working with streams (java.util.stream), I could not find the the actual class that implements the java.util.Collection.stream() method.

I have the following questions, when I say list.stream():

  1. Where do I get the java.util.stream.Stream from?
  2. How did they implement it without actually "disturbing" the existing collections?(assuming that they did not touch them)

I did try to look through the documentations of java.util.AbstractCollection and java.util.AbstractList but was unable to find it.

Upvotes: 18

Views: 4056

Answers (6)

Mahadev Mandale
Mahadev Mandale

Reputation: 447

We will get java.util.stream.Stream object from the Collection interface's default method stream(); and it is possible because of default methods which is introduced in Java 8.

Before java 8 we could only declare methods in an interface. From Java 8 we can also define methods or default methods in an interface.

In our case stream() is a default method from the interface Collection. For example in below case when you do list.stream() the default method stream() of Collection will get called and it will convert list of objects to Stream and return it back so that you can process it further as per your need using operations such as filter, map, flatMap etc.

List<String> list = Arrays.asList("abc","pqr","xyz");
Stream<String> stream = list.stream();

Upvotes: 0

Junior Mbe
Junior Mbe

Reputation: 1

"stream" is just a name to group the functional aspect behind. The real implementation is in the java.util.stream.ReferencePipeline class.

This is where you can see the code applied during intermediate and final operations. To go from a Collection to a Stream for example, you can follow the path

Collection::stream() -> StreamSupport::stream() -> ReferencePipeline.Head

Upvotes: 0

Jeremy Grand
Jeremy Grand

Reputation: 2388

Java 8 allows the definition of default methods in interfaces.

Collection<E> then defines :

default Stream<E> stream() {
    return StreamSupport.stream(spliterator(), false);
}

That's how they added it.

Upvotes: 20

Eugene
Eugene

Reputation: 121048

You did not see it in ArrayList because it is defined in Collection as a default method (you have probably got that this already). But it could have been defined in ArrayList or any other Collection, thus overriding it. For example it is defined in CopiesList as :

    @Override
    public Stream<E> stream() {
        return IntStream.range(0, n).mapToObj(i -> element);
    }

Thus overriding the one from Collection; this means it is not always the one from the super class.

Upvotes: 9

Tamas Hegedus
Tamas Hegedus

Reputation: 29946

As others pointed out, the .stream() method is implemented as a default method in the Collection interface itself, as you can see it in the method signature in the official documentation:

default Stream<E> stream()

How the stream interface is implemented is an implementation detail of the collection. However, implementing the same heavy Stream interface for every collection would be a lot of work and duplication, so they use an intermediate abstraction called Spliterator.

This SO thread on .stream() might be worth reading as well.

Upvotes: 16

Florian Sesser
Florian Sesser

Reputation: 6154

It's a default method (another Java 8 feature) in the Collection interface definition. See Collection.java Line 580 for the code:

default Stream<E> stream() {
   return StreamSupport.stream(spliterator(), false);
}

Upvotes: 8

Related Questions