0

I have this object:

String[] stringNum = new String[] {"1", "2", "3", "4", "5", "6", "7"};

And I'm having some trouble to understand why this works:

 List<Integer> intNums = Arrays.stream(stringNum)
                                .map(Integer::parseInt)
                                .collect(Collectors.toList());

But this doesn't:

 List<Integer> intNums = Arrays.stream(stringNum)
                                .mapToInt(Integer::parseInt)
                                .collect(Collectors.toList());

If I understood to correctly then both .map(Integer::parseInt) and .mapToInt(Integer::parseInt) should return the same IntStream in this case to be handled by .collect(Collectors.toList()).

TalG
  • 677
  • 1
  • 9
  • 26

2 Answers2

3

.map(Integer::parseInt) returns a Stream<Integer>, not an IntStream. That's why the first snippet works.

IntStream doesn't have a collect() method that accepts a Collector. Therefore, the second snippet, which maps the Stream<String> to an IntStream cannot use .collect(Collectors.toList()).

To use the collect(Supplier<R> supplier,ObjIntConsumer<R> accumulator,BiConsumer<R, R> combiner) method of IntStream you can write:

List<Integer> intNums = Arrays.stream(stringNum)
                              .mapToInt(Integer::parseInt)
                              .collect(ArrayList::new,ArrayList::add,ArrayList::addAll);

However, since your output is a List<Integer>, there's no point to create the intermediate IntStream, since that would require to box the ints later. Your Stream<Integer> variant (first snippet) makes more sense.

Eran
  • 387,369
  • 54
  • 702
  • 768
  • in addition to use `.map(Integer::valueOf)` instead `.map(Integer::parseInt)` – Hadi J Apr 13 '20 at 09:52
  • @HadiJ since `Integer.valueOf()` calls `Integer.parseInt()`, I believe it won't save anything. Either way a boxing will take place. – Eran Apr 13 '20 at 09:56
0

mapToInt gives an IntStream, which doesn't have collect method taking a Collector argument.

CodeScale
  • 3,046
  • 1
  • 12
  • 20