Я щойно відкрив нові можливості потоку Java 8. Походячи з Python, мені було цікаво, чи не існує тепер акуратного способу робити операції над масивами, як підсумовування, множення двох масивів "пітонічним" одним рядком?
Дякую
Я щойно відкрив нові можливості потоку Java 8. Походячи з Python, мені було цікаво, чи не існує тепер акуратного способу робити операції над масивами, як підсумовування, множення двох масивів "пітонічним" одним рядком?
Дякую
Відповіді:
Додано нові методи 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();
mapToInt
щоб уникнути боксу.
Ви можете перетворити масив у потік, використовуючи 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();
Будьте уважні, якщо вам доведеться мати справу з великою кількістю.
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
Зауважте, що Arrays.stream (arr) створює LongStream (або IntStream, ...) замість Stream, тому функцію карти не можна використовувати для зміни типу. Ось чому передбачені функції .mapToLong, mapToObject, ....
Подивіться, чому-cant-i-map-integers-to-strings-when-streaming-from-an-array
int[] result=IntStream.range(0, a.length).map( i->a[i]* b[i]).toArray();