Java 8 Streaming dan operasi pada array


197

Saya baru saja menemukan kemampuan Java 8 stream yang baru. Berasal dari Python, saya bertanya-tanya apakah sekarang ada cara yang rapi untuk melakukan operasi pada array seperti menjumlahkan, mengalikan dua array dalam cara "satu baris pythonic"?

Terima kasih

Jawaban:


294

Ada metode baru yang ditambahkan untuk java.util.Arraysmengubah array menjadi aliran Java 8 yang kemudian dapat digunakan untuk menjumlahkan dll.

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

Mengalikan dua array sedikit lebih sulit karena saya tidak bisa memikirkan cara untuk mendapatkan nilai DAN indeks pada saat yang sama dengan operasi Stream. Ini berarti Anda mungkin harus melakukan streaming indeks array.

//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 menunjukkan Anda dapat menggunakan mapmetode bukan forEachseperti ini:

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();
Holger

2
@ Holger ya itu akan berhasil juga. Meskipun Anda mungkin ingin menggunakan mapToIntuntuk menghindari tinju.
dkatzel

Yang terakhir merupakan simulasi zip di mana Anda harus melakukan pra-alokasi penyimpanan untuk hasilnya. Saya bertanya-tanya mengapa tidak ada zip di perpustakaan Streams?
Reb.Cabin

Menurut jawaban SO ini , sebuah zip ada di beta Java 8 yang lebih awal, kemudian dikeluarkan. Untungnya poster itu memiliki sumber dan jawabannya ada. Saya telah menggunakan kode beberapa kali dan sepertinya berfungsi dengan sangat baik.
sparc_spread

@dkatzel - Karena sudah menjadi IntStream, "peta" menggunakan IntUnaryOperator, jadi tidak ada tinju yang terlibat.
M. Justin

58

Anda dapat mengubah array menjadi aliran dengan menggunakan Arrays.stream():

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

Setelah Anda mendapatkan aliran Anda, Anda dapat menggunakan salah satu metode yang dijelaskan dalam dokumentasi , seperti sum()atau apa pun. Anda bisa mapatau filtersuka dengan Python dengan memanggil metode stream yang relevan dengan fungsi Lambda:

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

Setelah selesai memodifikasi aliran Anda, Anda kemudian menelepon toArray()untuk mengubahnya kembali menjadi array untuk digunakan di tempat lain:

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

Hati-hati jika harus berhadapan dengan jumlah besar.

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

Jumlah di atas tidak 2 * Integer.MIN_VALUE. Anda perlu melakukan ini dalam hal ini.

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.