399

I'm looking at the docs for the IntStream, and I see an toArray method, but no way to go directly to a List<Integer>

Surely there is a way to convert a Stream to a List?

skiwi
  • 66,971
  • 31
  • 131
  • 216
Eric Wilson
  • 57,719
  • 77
  • 200
  • 270
  • Try this link:http://stackoverflow.com/questions/14830313/retrieving-a-list-from-a-java-util-stream-stream-in-java8 – Vaibhav Jain May 15 '14 at 09:46
  • 2
    @KarlRichter The other question doesn't give you a typed list. Also, this question was from four years ago, and has an answer with 300+ upvotes. Why are we trying to merge it now? – Eric Wilson Apr 18 '18 at 17:35

5 Answers5

738

IntStream::boxed

IntStream::boxed turns an IntStream into a Stream<Integer>, which you can then collect into a List:

theIntStream.boxed().collect(Collectors.toList())

The boxed method converts the int primitive values of an IntStream into a stream of Integer objects. The word "boxing" names the int ⬌ Integer conversion process. See Oracle Tutorial.

Java 16 and later

Java 16 brought the shorter toList method. Produces an unmodifiable list. Discussed here.

theIntStream.boxed().toList() 
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Ian Roberts
  • 120,891
  • 16
  • 170
  • 183
  • 1
    @skiwi I mean, that all the other answers are unneeded after this one as they would be not so natural. – Dmitry Ginzburg May 15 '14 at 09:56
  • 1
    Thank you I hadn't seen the boxed method yet and it worked like a charm. – twreid Jan 05 '16 at 15:07
  • 1
    Addition: I think this codes gets a little shorter, clearer and prettier if you use a static import of `toList`. This is done by placing the following among the imports of the file: `static import java.util.stream.Collectors.toList;`. Then the collect call reads just `.collect(toList())`. – Lii Jun 29 '16 at 09:00
  • 1
    In Eclipse it is possible to make the IDE add a static import for methods. This is done by adding the `Collectors` class in *Preferences* -> *Java* -> *Editor* -> *Content Assist* -> *Favorites*. After this, you only have to type `toLi` at hit *Ctr+Space* to have the IDE fill in `toList` and add the static import. – Lii Jun 29 '16 at 09:00
  • 3
    Was tearing my hair out about what was wrong with what I had tried, thank you for pointing out the `boxed()` part – K Raphael Sep 28 '17 at 15:40
  • Don't forget to `import java.util.stream.Collectors;`. – byxor Dec 15 '17 at 19:54
  • 1
    I was happy to get this answer -- and more broadly, these features in Java 8. Looking back after two years working in Python, and I'm so glad I don't have to deal with this nonsense. – Eric Wilson Feb 15 '18 at 20:14
  • java stream api is un-straightforward at so many levels.. – Marinos An Feb 15 '21 at 15:59
25

You could also use mapToObj() on a Stream, which takes an IntFunction and returns an object-valued Stream consisting of the results of applying the given function to the elements of this stream.

List<Integer> intList = myIntStream.mapToObj(i->i).collect(Collectors.toList());
Ida Bucić
  • 939
  • 8
  • 10
9

You can use primitive collections available in Eclipse Collections and avoid boxing.

MutableIntList list = 
    IntStream.range(1, 5)
    .collect(IntArrayList::new, MutableIntList::add, MutableIntList::addAll);

Note: I am a contributor to Eclipse Collections.

Nikhil Nanivadekar
  • 1,152
  • 11
  • 10
  • 6
    Although Eclipse Collections are usually quite helpful, this does not look like it is making anything easier at all :) – Ben Dec 20 '17 at 12:32
  • 2
    Since EC 9.0, you can build a primitive list from a primitive Stream. `MutableIntList list = IntLists.mutable.withAll(IntStream.range(1, 5))` – Donald Raab Jan 11 '19 at 21:53
  • 2
    This is what I was looking for .. boxing the int stream to Integer or to object is different thing – Vikash Apr 11 '19 at 08:02
8

You can use the collect method:

IntStream.of(1, 2, 3).collect(ArrayList::new, List::add, List::addAll);

In fact, this is almost exactly what Java is doing when you call .collect(Collectors.toList()) on an object stream:

public static <T> Collector<T, ?, List<T>> toList() {
    return new Collectors.CollectorImpl(ArrayList::new, List::add, (var0, var1) -> {
        var0.addAll(var1);
        return var0;
    }, CH_ID);
}

Note: The third parameter is only required if you want to run parallel collection; for sequential collection providing just the first two will suffice.

Harry Jones
  • 336
  • 3
  • 8
3

Find the folowing example of finding square of each int element using Java 8 :-

IntStream ints = Arrays.stream(new int[] {1,2,3,4,5});       
List<Integer> intsList = ints.map(x-> x*x)
          .collect(ArrayList<Integer>::new, ArrayList::add, ArrayList::addAll);
Anoob C I
  • 171
  • 13
Vikash
  • 2,046
  • 3
  • 23
  • 30