it-swarm.com.ru

Java 8 Поток и работа с массивами

Я только что обнаружил новые возможности потока Java 8. Исходя из Python, мне было интересно, есть ли сейчас удобный способ выполнять операции над массивами, такие как суммирование, умножение двух массивов способом "Pythonic" в одну строку?

Спасибо

186
BlackLabrador

В Java.util.Arrays добавлены новые методы для преобразования массива в поток Java 8, который затем можно использовать для суммирования и т.д.

int sum =  Arrays.stream(myIntArray)
                 .sum();

Умножение двух массивов немного сложнее, потому что я не могу придумать способ получить значение И индекс одновременно с операцией Stream. Это означает, что вам, вероятно, придется перемещаться по индексам массива.

//in this example a[] and b[] are same length
int[] a = ...
int[] b = ...

int[] result = new int[a.length];

IntStream.range(0, a.length)
         .forEach(i -> result[i] = a[i] * b[i]);

РЕДАКТИРОВАТЬ

Commenter @ Holger указывает, что вы можете использовать метод map вместо forEach, например так:

int[] result = IntStream.range(0, a.length).map(i -> a[i] * b[i]).toArray();
285
dkatzel

Вы можете превратить массив в поток с помощью Arrays.stream():

int[] ns = new int[] {1,2,3,4,5};
Arrays.stream(ns);

После того, как вы получили свой поток, вы можете использовать любой из методов, описанных в документация , например, sum() или любой другой. Вы можете map или filter, как в Python, вызвав соответствующие методы потока с помощью функции Lambda:

Arrays.stream(ns).map(n -> n * 2);
Arrays.stream(ns).filter(n -> n % 4 == 0);

Как только вы закончите модифицировать ваш поток, вы вызываете toArray(), чтобы преобразовать его обратно в массив для использования в другом месте:

int[] ns = new int[] {1,2,3,4,5};
int[] ms = Arrays.stream(ns).map(n -> n * 2).filter(n -> n % 4 == 0).toArray();
56
Ian Knight

Будьте осторожны, если вам приходится иметь дело с большими числами.

int[] arr = new int[]{Integer.MIN_VALUE, Integer.MIN_VALUE};
long sum = Arrays.stream(arr).sum(); // Wrong: sum == 0

Вышеуказанная сумма не является 2 * Integer.MIN_VALUE. Вы должны сделать это в этом случае.

long sum = Arrays.stream(arr).mapToLong(Long::valueOf).sum(); // Correct
9
Sanghyun Lee

Обратите внимание, что Arrays.stream (arr) создает LongStream (или IntStream, ...) вместо Stream, поэтому функцию map нельзя использовать для изменения типа. Вот почему .mapToLong, mapToObject, ... функции предоставляются.

Взгляните на почему-не-я-карта-целые-для-строки-когда-поток-из-массива

3
Rafael