Bagaimana cara mengubah Java 8 Stream ke Array?


775

Apa cara termudah / terpendek untuk mengubah Java 8 Streammenjadi sebuah array?


2
Saya sarankan Anda untuk mengembalikan rollback karena pertanyaannya lebih lengkap dan menunjukkan Anda telah mencoba sesuatu.
skiwi

2
@skiwi Terima kasih! tetapi saya pikir kode yang dicoba tidak benar-benar menambahkan lebih banyak informasi ke pertanyaan, dan tidak ada yang berteriak "tunjukkan usaha Anda" yet =)

17
@skiwi: Meskipun saya biasanya meneriaki pertanyaan do-my-PR-alih-alih-saya, pertanyaan khusus ini tampaknya lebih jelas bagi saya tanpa kekacauan tambahan. Mari kita tetap rapi.
Honza Zidek

Anda dapat menemukan banyak jawaban dan panduan dalam dokumen resmi paket: docs.oracle.com/javase/8/docs/api/java/util/stream/…
Christophe

Jawaban:


1168

Metode termudah adalah menggunakan toArray(IntFunction<A[]> generator)metode dengan referensi konstruktor array. Ini disarankan dalam dokumentasi API untuk metode ini .

String[] stringArray = stringStream.toArray(String[]::new);

Apa yang dilakukannya adalah menemukan metode yang menggunakan integer (ukuran) sebagai argumen, dan mengembalikan a String[], yang persis seperti apa (salah satu kelebihan beban) new String[]tidak.

Anda juga bisa menulis sendiri IntFunction:

Stream<String> stringStream = ...;
String[] stringArray = stringStream.toArray(size -> new String[size]);

Tujuannya IntFunction<A[]> generatoradalah untuk mengkonversi bilangan bulat, ukuran array, ke array baru.

Kode contoh:

Stream<String> stringStream = Stream.of("a", "b", "c");
String[] stringArray = stringStream.toArray(size -> new String[size]);
Arrays.stream(stringArray).forEach(System.out::println);

Cetakan:

a
b
c

8
dan inilah penjelasan mengapa dan bagaimana referensi konstruktor Array benar-benar berfungsi: stackoverflow.com/questions/29447561/…
jarek.jpa

"Zenexer benar, solusinya adalah: stream.toArray (String [] :: new);" ... Baiklah ok, tetapi orang harus memahami bahwa referensi metode secara logis dan fungsional setara dengan toArray(sz -> new String[sz])jadi saya tidak yakin bahwa seseorang dapat benar-benar mengatakan apa solusi yang seharusnya atau harus dilakukan.
scottb

3
@scottb sz -> new String[sz]membuat fungsi baru sedangkan referensi konstruktor tidak. Itu tergantung berapa banyak Anda menghargai Pengumpulan Sampah Churn kurasa.
WORMSS

3
@WORMSS Tidak. Ini (secara statis!) Membuat private metode baru , yang tidak dapat menyebabkan churn, dan kedua versi perlu membuat objek baru. Referensi membuat objek yang menunjuk langsung ke metode target; sebuah lambda membuat objek yang menunjuk ke objek yang dihasilkan private. Referensi ke konstruktor harus tetap berkinerja lebih baik karena kurangnya tipuan dan optimisasi VM yang lebih mudah, tetapi mengaduk tidak ada hubungannya dengan itu.
HTNW

2
@ HTNW Anda benar, saya minta maaf. Itu adalah usaha saya untuk men-debug yang menyebabkan churn yang menyebabkan churn pertama kali saya mencoba melakukan ini, jadi saya sudah terjebak di kepala saya bahwa ini adalah bagaimana itu. (Benci ketika itu terjadi).
KARYA

41

Jika Anda ingin mendapatkan array int, dengan bentuk nilai 1 hingga 10, dari Stream, ada IntStream yang Anda inginkan.

Di sini kita membuat Stream dengan metode Stream.of dan mengonversi Stream ke IntStream menggunakan mapToInt. Lalu kita bisa memanggil metode toArray IntStream.

Stream<Integer> stream = Stream.of(1,2,3,4,5,6,7,8,9,10);
//or use this to create our stream 
//Stream<Integer> stream = IntStream.rangeClosed(1, 10).boxed();
int[] array =  stream.mapToInt(x -> x).toArray();

Ini adalah hal yang sama, tanpa Stream, hanya menggunakan IntStream

int[]array2 =  IntStream.rangeClosed(1, 10).toArray();

16

Anda dapat mengonversi aliran java 8 ke array menggunakan blok kode sederhana ini:

 String[] myNewArray3 = myNewStream.toArray(String[]::new);

Tapi mari kita jelaskan lebih banyak, pertama, mari kita buat daftar string yang diisi dengan tiga nilai:

String[] stringList = {"Bachiri","Taoufiq","Abderrahman"};

Buat aliran dari Array yang diberikan:

Stream<String> stringStream = Arrays.stream(stringList);

kita sekarang dapat melakukan beberapa operasi pada aliran ini, Ex:

Stream<String> myNewStream = stringStream.map(s -> s.toUpperCase());

dan akhirnya mengubahnya menjadi java 8 Array menggunakan metode ini:

Metode 1-Klasik (Antarmuka fungsional)

IntFunction<String[]> intFunction = new IntFunction<String[]>() {
    @Override
    public String[] apply(int value) {
        return new String[value];
    }
};


String[] myNewArray = myNewStream.toArray(intFunction);

2 -Lambda ekspresi

 String[] myNewArray2 = myNewStream.toArray(value -> new String[value]);

3- Referensi metode

String[] myNewArray3 = myNewStream.toArray(String[]::new);

Referensi metode Penjelasan:

Ini adalah cara lain untuk menulis ekspresi lambda yang sangat setara dengan yang lain.


7

Konversi teks ke array string tempat memisahkan setiap nilai dengan koma, dan potong setiap bidang, misalnya:

String[] stringArray = Arrays.stream(line.split(",")).map(String::trim).toArray(String[]::new);

5

Anda dapat membuat kolektor khusus yang mengonversi aliran ke array.

public static <T> Collector<T, ?, T[]> toArray( IntFunction<T[]> converter )
{
    return Collectors.collectingAndThen( 
                  Collectors.toList(), 
                  list ->list.toArray( converter.apply( list.size() ) ) );
}

dan penggunaan cepat

List<String> input = Arrays.asList( ..... );

String[] result = input.stream().
         .collect( CustomCollectors.**toArray**( String[]::new ) );

5
Mengapa Anda menggunakan ini alih-alih Stream.toArray (IntFunction) ?
Didier L

Saya membutuhkan seorang kolektor untuk meneruskan ke 2-arg Collectors.groupingBysehingga saya bisa memetakan beberapa atribut ke array objek per nilai atribut. Jawaban ini memberi saya persis seperti itu. Juga @Dierier.
Ole VV

3

Menggunakan toArray(IntFunction<A[]> generator)metode ini memang cara yang sangat elegan dan aman untuk mengonversi (atau lebih tepatnya, mengumpulkan) Stream menjadi array dengan tipe Stream yang sama.

Namun, jika jenis array yang dikembalikan tidak penting, cukup menggunakan toArray()metode ini lebih mudah dan lebih pendek. Sebagai contoh:

    Stream<Object> args = Stream.of(BigDecimal.ONE, "Two", 3);
    System.out.printf("%s, %s, %s!", args.toArray());

0
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);

int[] arr=   stream.mapToInt(x->x.intValue()).toArray();

0
import java.util.List;
import java.util.stream.Stream;

class Main {

    public static void main(String[] args) {
        // Create a stream of strings from list of strings
        Stream<String> myStreamOfStrings = List.of("lala", "foo", "bar").stream();

        // Convert stream to array by using toArray method
        String[] myArrayOfStrings = myStreamOfStrings.toArray(String[]::new);

        // Print results
        for (String string : myArrayOfStrings) {
            System.out.println(string);
        }
    }
}

Cobalah secara online: https://repl.it/@SmaMa/Stream-to-array


Apa perbedaan antara jawaban Anda dan jawaban yang diterima?
Long Nguyen

@ LongNguyen Ini adalah contoh lengkap termasuk skenario pemutaran ulang online, tidak hanya cuplikan.
Sma Ma

-1
     Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);

     Integer[] integers = stream.toArray(it->new Integer[it]);

-2

Anda dapat melakukannya dalam beberapa cara. Semua cara secara teknis sama tetapi menggunakan Lambda akan menyederhanakan beberapa kode. Katakanlah kita menginisialisasi Daftar terlebih dahulu dengan String, sebut saja orang.

List<String> persons = new ArrayList<String>(){{add("a"); add("b"); add("c");}};
Stream<String> stream = persons.stream();

Sekarang Anda dapat menggunakan salah satu dari cara berikut.

  1. Menggunakan Lambda Expresiion untuk membuat StringArray baru dengan ukuran yang ditentukan.

    String [] stringArray = stream.toArray (size-> new String [size]);

  2. Menggunakan referensi metode secara langsung.

    String [] stringArray = stream.toArray (String [] :: new);

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.