Bir diziden nasıl akış oluşturabilirim?


133

Şu anda bir diziden akış oluşturmam gerektiğinde,

String[] array = {"x1", "x2"};
Arrays.asList(array).stream();

Bir diziden akış oluşturmanın doğrudan bir yolu var mı?

Yanıtlar:


201

Arrays.stream Eg kullanabilirsiniz.

Arrays.stream(array);

Ayrıca Stream.of, @fge tarafından belirtildiği gibi kullanabilirsiniz.

public static<T> Stream<T> of(T... values) {
    return Arrays.stream(values);
}

Ama dikkat Stream.of(intArray)dönecektir Stream<int[]>oysa Arrays.stream(intArr)dönecektir IntStreamEğer türü bir dizi geçmesi sağlayarak int[]. Yani ilkel tip için bir özetle, 2 yöntem arasındaki farkı gözlemleyebilirsiniz.

int[] arr = {1, 2};
Stream<int[]> arr1 = Stream.of(arr);

IntStream stream2 = Arrays.stream(arr); 

İlkel diziyi Arrays.streamilettiğinizde, aşağıdaki kod çağrılır

public static IntStream stream(int[] array) {
    return stream(array, 0, array.length);
}

ve ilkel diziyi geçirdiğinizde Stream.ofaşağıdaki kod çağrılır

 public static<T> Stream<T> of(T t) {
     return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
 }

Böylece farklı sonuçlar elde edersiniz.

Güncellendi : Stuart Marks yorumunda belirtildiği gibi, alt Arrays.streamöğesinin aşırı yüklenmesinin kullanılması tercih edilir, Stream.of(array).skip(n).limit(m)çünkü eski boyutlar SIZED akışıyla sonuçlanırken ikincisi bunu yapmaz. Bunun nedeni ise limit(m), oysa boyut m veya daha az m'den olup olmadığını bilmiyor Arrays.streamaralık kontrolleri yapar ve Sen tarafından döndürülen akış uygulaması için kaynak kodunu okuyabilir akışının tam boyutunu bilir Arrays.stream(array,start,end) burada akışı için uygulama tarafından döndürülen oysa Stream.of(array).skip().limit()DİR bu yöntem dahilinde .


9
Bu cevap daha iyidir, çünkü Arrays.streamilkel diziler için aşırı yüklenmiş durumlar vardır. Yani Stream.of(new int[]{1,2,3})bir verecektir Stream<int[]>oysa Arrays.streamverecek bir geri IntStreamistediğini muhtemelen hangi. Yani +1
user2336315

3
@ Sanırım bu bir zevk meselesi. Bir anlamda daha iyi bir Stream.ofsürpriz verebilir ( Arrays.asListilkel bir dizi ile aradığınızda ve insanların bir List<Integer>geri beklediğiniz gibi ) :-)
user2336315

3
Arrays.streamdizinin, bir dizi akışı destekler IntStream.ofdeğil. Buna karşılık, bir boyut istiyorsanızStream.of daha iyi bir seçimdir …Stream<int[]>1
Holger

4
@Dima Alt aralık aşırı yüklenmesinin Arrays.streamkullanılması tercih edilir Stream.of(array).skip(n).limit(m)çünkü birincisi SIZED akışıyla sonuçlanırken ikincisi bunu yapmaz. Bunun nedeni, limit(m)boyutun mküçük veya küçük olup olmadığını bilmediği mhalde Arrays.stream, aralık akışın tam boyutunu denetler ve bilir.
Stuart Marks

6
Bu küçük dram sonucuna görmeye ilgilenen edilir okuyucuları için Arrays.stream(array,start,end)bir döner Streamkimin uygulamasıdır burada , oysa Stream.of(array).skip().limit()bir getiri Streamgerçekleştirme aşamasında içindedir bu yöntemle .
Stuart Marks

43

@ Sol4me'nin çözümüne alternatif:

Stream.of(theArray)

Bu ve arasındaki farkın Arrays.stream(): Bu mu senin dizi ilkel türden olduğu takdirde bir fark yaratır. Örneğin, şunları yaparsanız:

Arrays.stream(someArray)

nerede someArraya long[], geri dönecektir a LongStream. Stream.of(), diğer taraftan, Stream<long[]>tek bir öğeyle birlikte a döndürür .


1
@Dima emin, ama Arrays.stream()bunun için de çalışıyor
fge

2
Akarsu gelince, kolaylık! Gerek aramak *Stream.of()sen varken Arrays.stream()ilkel diziler ile uğraşırken. Ve diziler gerçek nesneler olmamaya gelince, bu Java, 1.0'dan beri durum böyle; Bunun üzerine
düşünmek

2
@Dima ve sizin de öyle; Eğer düşünün Arrays.stream(), uygun olmamaya ben o uygun olarak düşünün. Yeterince söylendi.
fge

2
@Dima evet, yanıltıcı olmak *Stream.of()için daha uygun olduğunu savunuyorum; çünkü bu bir tercih meselesi . Bu Arrays.stream()gibi durumları tercih ederim , bu da daha genel bir kural olarak yanlış yapar Stream.of()(Peano cebiri).
fge

3
@Dima: Bu bir tercih meselesi. Farklılıklar o kadar inanılmaz derecede küçük ki, hiç önemli değil. Daha spesifik olarak: birkaç karakter arasındaki fark hiçbir şey değildir . Bir pakete ek bir ithalat standart kütüphaneler içeride olduğunu şey . Ve gerçekten, varargs aşırı yükü yerine manuel olarak bir dizi oluşturmak hiçbir şey değildir .
Jeroen Vannevel

14
Stream.of("foo", "bar", "baz")

Veya zaten bir diziniz varsa,

Stream.of(array) 

İlkel tip kullanım için IntStream.ofya da LongStream.ofvs.


Anlamadığım şey, bir int[]varargs kabul eden bir yönteme geçirilebildiğinde, neden bunun yerine Stream.of(intArray)üretmeyesiniz ? Ayrıca, ilkeller için neden özel Stream sınıfları olduğuna dair teknik bir neden var mı? Stream<Integer>Stream<int[]>
asgs

1
Java ilkelleri tuhaf yaratıklardır. int[]diğer diziler gibi değil. Bu bir alt sınıfı değil Object[], ama olduğu bir alt sınıfıdır Object. Yani, ilettiğinizde , parametre Stream.ofolarak alınır Objectve bir akış elde edersiniz int[]. İlkel için özel sınıflara sahip olmanın nedenlerinden biri de budur - ilkel dizilerden akış oluşturmadıysanız oldukça acı verici olurdu. Diğer nedeni, tahakkuk gerekmez çünkü uzman sınıflar, daha verimli olmasıdır Objectboks gelen yükü (dönüştürme intiçin Integernormal nesneler gibi görünmesi için).
Dima

Ah, int[]bir Objectolduğu için aşırı yüklenmiş yöntemle eşleşir of(T t)ve dolayısıyla geri döner Stream<int[]>. Peki, teorik olarak, eğer bu yöntem mevcut olmasaydı, karşılığında biz var Stream<Integer>mıydık? ya da eşleştirme yöntemini bulamadığı için bir derleme hatasına neden olabilir? yani int[]muamele edilemezT...
asgs

1
Hayır, yine de Stream<Integer>bu şekilde elde edemeyiz , çünkü Stream.of(t ... T) yine de aynı şekilde eşleşirdi.
Dima

0

Paralel seçeneğe sahip düşük seviyeli yöntemle de yapabilirsiniz:

Güncelleme: Tam array.length kullanın (uzunluk - 1 değil).

/** 
 * Creates a new sequential or parallel {@code Stream} from a
 * {@code Spliterator}.
 *
 * <p>The spliterator is only traversed, split, or queried for estimated
 * size after the terminal operation of the stream pipeline commences.
 *
 * @param <T> the type of stream elements
 * @param spliterator a {@code Spliterator} describing the stream elements
 * @param parallel if {@code true} then the returned stream is a parallel
 *        stream; if {@code false} the returned stream is a sequential
 *        stream.
 * @return a new sequential or parallel {@code Stream}
 *
 * <T> Stream<T> stream(Spliterator<T> spliterator, boolean parallel)
 */

StreamSupport.stream(Arrays.spliterator(array, 0, array.length), true)

0

Arrays.stream komutunu kullanabilirsiniz:

(Dizi) Arrays.stream; 

Bu, dizi giriş türünüze göre geri dönüş buhar türünü sağlarsa, String []geri dönerse Stream<String>, int []geri dönerseIntStream

Giriş türü dizisini zaten biliyorsanız, giriş türü gibi belirli bir tür kullanmak iyi int[]

 IntStream.of (dizi); 

Bu, Intstream değerini döndürür.

İlk örnekte, Java overloading, girdi türlerine göre belirli bir yöntemi bulmak için yöntemi kullanır , ikinci sırada ise girdi türünü ve belirli yöntemi çağırmayı zaten biliyorsunuzdur.


0

nadiren görülür, ancak bu en doğrudan yoldur

Stream.Builder<String> builder = Stream.builder();
for( int i = 0; i < array.length; i++ )
  builder.add( array[i] );
Stream<String> stream = builder.build();
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.