Java 8 Akışı ve dizilerde çalışma


197

Yeni Java 8 akış yeteneklerini yeni keşfettim. Python'dan geldiğimde, iki diziyi "tek satırlı bir pitonik" şekilde çarparak, toplama gibi diziler üzerinde işlemler yapmanın düzgün bir yolu olup olmadığını merak ediyordum.

Teşekkürler

Yanıtlar:


294

java.util.ArraysBir diziyi Java 8 akışına dönüştürmek için eklenen ve daha sonra toplama vb. İçin kullanılabilecek yeni yöntemler vardır .

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

İki diziyi çoğaltmak biraz daha zordur çünkü bir AND işlemi ile aynı anda değer VE indeksi elde etmenin bir yolunu düşünemiyorum. Bu, muhtemelen dizinin dizinleri üzerinden akış yapmanız gerektiği anlamına gelir.

//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]);

DÜZENLE

Commenter @Holger , mapbunun yerine yöntemi kullanabileceğinizi belirtiyorforEach :

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 evet bu da işe yarar. Her ne kadar muhtemelen mapToIntboks önlemek için kullanmak istiyorum .
dkatzel

Sonuncusu, sonuç için depolamayı önceden yerleştirmeniz gereken bir zip simülasyonu demektir. Streams kütüphanesinde neden zip yok?
Reb.Cabin

Göre bu SO cevap , bir zip Java 8 önceki bir beta oldu sonra dışarı alınır. Neyse ki posterin kaynağı vardı ve cevapta. Kodu birkaç kez kullandım ve çok iyi çalışıyor gibi görünüyor.
sparc_spread

@dkatzel - Zaten bir IntStream olduğundan, "harita" bir IntUnaryOperator alır, bu yüzden bir boks dahil değildir.
M Justin

58

Bir diziyi aşağıdakileri kullanarak akışa dönüştürebilirsiniz Arrays.stream():

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

Eğer akışı var sonra, açıklanan yöntemlerden herhangi birini kullanabilirsiniz belgeleri gibi sum()ya da her neyse. Şunları yapabilirsiniz mapveya filterPython gibi Lambda fonksiyonu ile ilgili akışı yöntemlerini çağırarak:

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

Akışınızı değiştirdikten sonra, toArray()başka bir yerde kullanmak için tekrar bir diziye dönüştürmek için çağrı yaparsınız :

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

Büyük sayılarla uğraşmak zorundaysanız dikkatli olun.

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

Yukarıdaki toplam değildir 2 * Integer.MIN_VALUE. Bu durumda bunu yapmanız gerekir.

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

3

Arrays.stream (arr) öğesinin Stream yerine bir LongStream (veya IntStream, ...) oluşturduğunu ve böylece harita işlevinin türü değiştirmek için kullanılamayacağını unutmayın. Bu nedenle .mapToLong, mapToObject, ... işlevleri sağlanmıştır.

Bir diziden neden akış gerçekleştirirken neden-cant-i-map-integer'lardan dizelere bir göz atın

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.