Bagaimana saya bisa membuat aliran dari array?


133

Saat ini setiap kali saya perlu membuat aliran dari array, saya lakukan

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

Apakah ada cara langsung untuk membuat streaming dari array?

Jawaban:


201

Anda dapat menggunakan Arrays.stream Eg

Arrays.stream(array);

Anda juga dapat menggunakan Stream.ofseperti yang disebutkan oleh @fge, yang terlihat seperti

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

Tetapi note Stream.of(intArray)akan kembali Stream<int[]>sedangkan Arrays.stream(intArr)akan kembali IntStreamasalkan Anda melewati array tipe int[]. Jadi singkatnya untuk tipe primitif Anda dapat mengamati perbedaan antara 2 metode Misalnya

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

IntStream stream2 = Arrays.stream(arr); 

Ketika Anda meneruskan array primitif ke Arrays.stream, kode berikut dipanggil

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

dan ketika Anda meneruskan array primitif ke Stream.ofkode berikut dipanggil

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

Karenanya Anda mendapatkan hasil yang berbeda.

Diperbarui : Seperti yang disebutkan oleh komentar Stuart Marks Kelebihan subrange Arrays.streamlebih disukai untuk digunakan Stream.of(array).skip(n).limit(m)karena yang pertama menghasilkan aliran SIZED sedangkan yang kedua tidak. Alasannya adalah bahwa limit(m)tidak tahu apakah ukurannya m atau kurang dari m, sedangkan Arrays.streamapakah rentang memeriksa dan mengetahui ukuran aliran yang tepat. Anda dapat membaca kode sumber untuk implementasi aliran yang dikembalikan oleh Arrays.stream(array,start,end) sini , sedangkan untuk implementasi aliran yang dikembalikan oleh Stream.of(array).skip().limit()adalah dalam metode ini .


9
Jawaban ini lebih baik karena Arrays.streammemiliki semua kasus kelebihan untuk array primitif. Yaitu Stream.of(new int[]{1,2,3})akan memberi Anda Stream<int[]>sedangkan Arrays.streamakan memberi Anda kembali IntStreamyang mungkin apa yang Anda inginkan. Jadi +1
user2336315

3
@Dima saya rasa ini masalah selera. Maksud saya lebih baik dalam arti Stream.ofbisa memberi Anda beberapa kejutan (seperti ketika Anda menelepon Arrays.asListdengan array primitif dan bahwa orang mengharapkan List<Integer>kembali) :-)
user2336315

3
Arrays.streammendukung streaming berbagai array, yang IntStream.oftidak. Sebaliknya, Stream.ofadalah pilihan yang lebih baik jika Anda ingin suatu Stream<int[]>ukuran 1...
Holger

4
@Dima Overrange subrange Arrays.streamlebih disukai untuk digunakan Stream.of(array).skip(n).limit(m)karena yang sebelumnya menghasilkan aliran SIZED sedangkan yang terakhir tidak. Alasannya adalah bahwa limit(m)tidak tahu apakah ukurannya matau kurang dari itu m, sedangkan Arrays.streamrentang melakukan pengecekan dan mengetahui ukuran persis aliran.
Stuart Marks

6
Bagi pembaca yang tertarik untuk melihat drama kecil ini selesai, Arrays.stream(array,start,end)kembalilah Streamyang implementasinya ada di sini , sedangkan Stream.of(array).skip().limit()pengembalian Streamyang implementasinya ada dalam metode ini .
Stuart Marks

43

Alternatif solusi @ sol4me:

Stream.of(theArray)

Perbedaan antara ini dan Arrays.stream(): itu tidak membuat perbedaan jika array adalah tipe primitif. Misalnya, jika Anda melakukannya:

Arrays.stream(someArray)

dimana someArraya long[], itu akan mengembalikan a LongStream. Stream.of(), di sisi lain, akan mengembalikan a Stream<long[]>dengan elemen tunggal.


1
@Dima tentu saja, tetapi Arrays.stream()bekerja untuk itu juga
fge

2
Nah, untuk stream, kenyamanan! Tidak perlu menelepon *Stream.of()saat Anda Arrays.stream()berhadapan dengan array primitif. Dan untuk array tidak menjadi objek nyata, yah, ini adalah Java, ini telah terjadi sejak 1.0 jadi hadapi itu; merenung tentang ini tidak membantu
fge

2
@Dima dan begitu juga milikmu; Anda menganggap Arrays.stream()tidak nyaman, saya anggap nyaman. Cukup kata.
fge

2
@Dima ya, saya menemukan argumen Anda yang *Stream.of()lebih nyaman untuk menyesatkan; karena ini masalah preferensi . Saya lebih suka Arrays.stream()untuk kasus-kasus seperti itu, yang membuatnya salah sebagai aturan umum yang Stream.of()lebih nyaman (aljabar Peano).
fge

3
@Dima: ini masalah preferensi. Perbedaannya sangat kecil sehingga tidak masalah sama sekali. Lebih khusus: perbedaan beberapa karakter tidak ada artinya . Impor tambahan ke paket di dalam pustaka standar tidak ada artinya . Dan sungguh, secara manual membuat array bukannya kelebihan varargs bukanlah apa - apa .
Jeroen Vannevel

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

Atau, jika Anda sudah memiliki array, Anda juga bisa melakukannya

Stream.of(array) 

Untuk tipe primitif gunakan IntStream.ofatau LongStream.ofdll.


Yang tidak saya mengerti adalah, ketika sebuah int[]dapat diteruskan ke metode menerima varargs, mengapa tidak akan Stream.of(intArray)menghasilkan yang Stream<Integer>bukan Stream<int[]>? Juga, apakah ada alasan teknis mengapa ada kelas Stream khusus untuk primitif?
asgs

1
Primitif Jawa adalah binatang aneh. int[]tidak seperti array lainnya. Ini bukan subkelas dari Object[], tetapi merupakan subkelas dari Object. Jadi, ketika Anda meneruskannya Stream.of, itu diambil sebagai Objectparameter, dan Anda mendapatkan aliran int[]. Itulah salah satu alasan untuk memiliki kelas khusus untuk primitif - jika Anda tidak membuat aliran dari array primitif akan sangat menyakitkan. Alasan lain, adalah bahwa kelas khusus yang lebih efisien, karena tidak perlu dikenakan Objectbiaya overhead dari tinju (mengkonversi intuntuk Integeragar terlihat seperti objek normal).
Dima

Ah, karena int[]merupakan Object, itu akan cocok dengan metode kelebihan beban of(T t)dan karenanya kembali Stream<int[]>. Jadi, secara teori, jika metode ini tidak tersedia, kita akan mendapatkan Stream<Integer>imbalannya? atau mungkin itu menghasilkan kesalahan kompilasi karena tidak dapat menemukan metode yang cocok? yaitu int[]tidak dapat diperlakukan sebagaiT...
asgs

1
Tidak, kami masih belum mendapatkan Stream<Integer>itu, karena Stream.of(t ... T) masih akan cocok dengan cara yang sama.
Dima

0

Anda dapat membuatnya juga dengan metode level rendah yang memiliki opsi paralel:

Pembaruan: Gunakan full array.length (tidak panjang - 1).

/** 
 * 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

Anda dapat menggunakan Arrays.stream:

Arrays.stream (array); 

Ini memastikan tipe pengembalian steam berdasarkan pada tipe input array Anda jika String []kemudian kembali Stream<String>, jika int []kemudian kembaliIntStream

Ketika Anda sudah tahu tipe input array maka bagus untuk menggunakan yang spesifik seperti untuk tipe input int[]

 IntStream.of (array); 

Ini mengembalikan Intstream.

Dalam contoh pertama, Java menggunakan metode overloadinguntuk menemukan metode spesifik berdasarkan tipe input sedangkan seperti pada kedua Anda sudah tahu jenis input dan memanggil metode tertentu.


0

jarang terlihat, tetapi ini adalah cara yang paling langsung

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