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


197

Я щойно відкрив нові можливості потоку Java 8. Походячи з Python, мені було цікаво, чи не існує тепер акуратного способу робити операції над масивами, як підсумовування, множення двох масивів "пітонічним" одним рядком?

Дякую

Відповіді:


294

Додано нові методи 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]);

EDIT

Commenter @Holger вказує, що ви можете використовувати mapметод замість forEachцього:

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

13
int[] result=IntStream.range(0, a.length).map( i->a[i]* b[i]).toArray();
Холгер

2
@Holger так, це теж працюватиме. Хоча ви, мабуть, хочете використовувати, mapToIntщоб уникнути боксу.
dkatzel

Останнє означає моделювання поштового індексу, де потрібно попередньо виділити сховище для результату. Цікаво, чому в бібліотеці Streams немає zip?
Reb.Cabin

Відповідно до цієї відповіді ТА , поштовий індекс був у попередній бета-версії Java 8, а потім виймався. На щастя, у плаката було джерело, і воно є у відповіді. Я використовував код кілька разів, і він, здається, працює дуже добре.
sparc_spread

@dkatzel - Оскільки це вже IntStream, "map" приймає IntUnaryOperator, тому бокс не бере участь.
М. Джастін

58

Ви можете перетворити масив у потік, використовуючи 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();

9

Будьте уважні, якщо вам доведеться мати справу з великою кількістю.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.