Как мне преобразовать Java 8 IntStream в Список?

283

Я смотрю на документы для IntStream, и я вижу toArrayметод, но нет способа перейти непосредственно кList<Integer>

Конечно, есть способ конвертировать Streamв List?

Эрик Уилсон
источник
Попробуйте эту ссылку: stackoverflow.com/questions/14830313/…
Вайбхав Джайн
2
@KarlRichter Другой вопрос не дает вам типизированный список. Кроме того, этот вопрос был задан четыре года назад и имеет ответ более 300 голосов. Почему мы пытаемся объединить это сейчас?
Эрик Уилсон

Ответы:

541

IntStream::boxed

IntStream::boxedпревращает IntStreamв Stream<Integer>, который вы можете затем collectв List:

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

boxedМетод преобразует intпримитивные значения IntStreamв поток Integerобъектов. Слово «бокс» называет intIntegerпроцесс преобразования. Смотрите Oracle Tutorial .

Ян Робертс
источник
1
@skiwi Я имею в виду, что все остальные ответы после этого не нужны, так как они были бы не такими естественными.
Дмитрий Гинзбург
1
Спасибо, я еще не видел коробочный метод, и он работал как шарм.
twreid
Дополнение: я думаю, что этот код становится немного короче, яснее и красивее, если вы используете статический импорт toList. Это делается путем размещения следующих среди импорта файла: static import java.util.stream.Collectors.toList;. Тогда вызов вызова читает просто .collect(toList()).
Лий
1
В Eclipse можно заставить IDE добавить статический импорт для методов. Это делается путем добавления Collectorsкласса в Предпочтения -> Java -> Редактор -> Помощник по содержимому -> Избранное . После этого вам нужно всего лишь toLiнажать Ctrl + Space, чтобы заполнить IDE toListи добавить статический импорт.
Лий
2
Я рвал на себе волосы о том, что не так с тем, что я пробовал, спасибо, что указали на эту boxed()часть
K Raphael
16

Вы также можете использовать mapToObj () в потоке, который принимает IntFunction и возвращает объектно-ориентированный поток, состоящий из результатов применения данной функции к элементам этого потока.

List<Integer> intList = myIntStream.mapToObj(i->i).collect(Collectors.toList());
Ида Бучич
источник
4
По иронии судьбы это то, что boxed()делегирует.
Макото
9

Вы можете использовать примитивные коллекции, доступные в Eclipse Collections, и избегать бокса.

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

Примечание: я участвую в коллекциях Eclipse.

Нихил Нанивадекар
источник
6
Хотя коллекции Eclipse, как правило, весьма полезны, это не похоже на то, что это вообще что-то облегчает :)
Ben
1
Начиная с EC 9.0, вы можете создавать примитивный список из примитивного потока. MutableIntList list = IntLists.mutable.withAll(IntStream.range(1, 5))
Дональд Рааб
1
Это то, что я искал ... упаковывать int-поток в Integer или в объект - это совсем другое
Викаш
2

Найдите следующий пример нахождения квадрата каждого элемента int с использованием 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);
Vikash
источник
0

Вы можете использовать метод сбора:

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

Фактически, это почти то же самое, что делает Java, когда вы вызываете .collect (Collectors.toList ()) в потоке объекта:

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);
}

Примечание. Третий параметр необходим, только если вы хотите запустить параллельный сбор; для последовательного сбора достаточно первых двух.

Гарри Джонс
источник