Какой метод в Java Stream API использовать для преобразования массива в стрим
Что проверяют
Знаете ли вы Arrays.stream и его перегрузки, а главное, различаете ли массив примитивов и массив объектов. Следом почти всегда дают ловушку: что вернёт Stream.of(new int[]{1, 2, 3}).
Как отвечать
Основной ответ: Arrays.stream(array). Тип результата зависит от типа массива:
T[]:Arrays.stream(T[])даётStream<T>, то же делаетStream.of(T...);int[],long[],double[]: отдельные перегрузки возвращаютIntStream,LongStreamиDoubleStream. Они работают без упаковки и сразу даютsum(),average(),summaryStatistics();- диапазон:
Arrays.stream(array, from, to)берёт кусок массива, правая граница не включается; - нужен
Stream<Integer>:Arrays.stream(ints).boxed(). Упаковку делают, только когда без неё не обойтись, например передtoList()илиcollect(Collectors.toList()).
Для char[], byte[], short[], float[] и boolean[] перегрузок нет. Для символов удобно new String(chars).chars() или CharBuffer.wrap(chars).chars(), для остальных IntStream.range(0, a.length).map(i -> a[i]).
Полезно сказать, что стрим не копирует массив, а читает его по мере выполнения терминальной операции. Менять массив, пока стрим не отработал, нельзя: это нарушает требование невмешательства из документации java.util.stream. Стрим из массива заранее знает свой размер, поэтому хорошо делится на части при parallel(), но параллельность окупается только на больших объёмах и дорогих операциях.
Где спотыкаются
Пишут Stream.of(intArray) и получают Stream<int[]> из одного элемента. Varargs не распаковывает массив примитивов, потому что int[] сам по себе объект. С Arrays.asList(intArray) та же ловушка: получается List<int[]>.
Упаковывают без нужды: boxed() ради суммы, а потом mapToInt обратно. На больших массивах это лишние объекты и нагрузка на GC.
Делают двойное преобразование вроде Arrays.stream(Arrays.stream(a).boxed().toArray(Integer[]::new)): массив копируется в промежуточный массив объектов, хотя достаточно Arrays.stream(a).boxed().