Bagaimana memahami metode Java 8 Stream collect () ini?

12

Saya mencoba untuk mengubah array int ke Daftar dan saya mengambil rute asing menggunakan Java 8 Stream dan datang dengan ini

Arrays.stream(arr).boxed().collect(Collectors.toList());

Saya masih mengalami kesulitan untuk sepenuhnya memahami kalimat ini, kebanyakan,

  1. Mengapa Collectors.toList()dalam hal ini mengembalikan antarmuka ArrayList<Integer>pelaksana List? Mengapa tidak LinkedList<Integer>atau kelas generik lain yang sesuai dengan Listantarmuka? Saya tidak dapat menemukan apa pun tentang ini, kecuali untuk penyebutan singkat tentang ArrayList di sini , di bagian Catatan API.

  2. Apa artinya panel kiri ? Jelas adalah tipe pengembalian generik ( dalam kode saya di sini). Dan saya pikir argumen tipe generik dari metode ini, tetapi bagaimana mereka ditentukan? Saya melihat ke antarmuka antarmuka Collector dan tidak dapat menyerapnya.masukkan deskripsi gambar di sini Stream.collect()RArrayList<Integer><R, A>

pengguna3207158
sumber
2
1. Itu memang menggunakan daftar aktual di bawah tenda, jelas. Tapi itu tidak bijaksana bagi suatu API untuk mengungkapkan tipe Daftar mendasar yang sebenarnya. Sejak itu mereka tidak akan pernah bisa mengubah implementasinya lagi di masa depan. Secara umum, sering kali merupakan ide yang baik untuk hanya mengekspos antarmuka dan tidak pernah tipe yang mendasarinya. 2. Radalah tipe generik dari tipe yang dihasilkan. Atipe generik dari tipe akumulasi menengah Kolektor. Itu adalah detail implementasi tentang cara kerja kolektor. Itu membagi dan menaklukkan, juga untuk pemrosesan paralel, mengumpulkan pertama menjadi tipe perantara.
Zabuzard
10
Anda hampir tidak pernah benar - benar menginginkan LinkedList. Ada tweet dari Josh Bloch , yang mengatakan "Saya menulisnya, dan saya tidak pernah menggunakannya".
Andy Turner
4
"Mengapa Collectors.toList()dalam kasus ini mengembalikan sebuah ArrayList<Integer>" Itu mungkin tidak mengembalikan sebuah ArrayList. The Listimplementasi terdefinisi , sehingga Anda tidak bisa mengandalkan apa implementasi itu kembali. Seperti yang dikatakan javadoc : "Tidak ada jaminan pada jenis , mutabilitas, serializability, atau keamanan thread dari Daftar yang dikembalikan;"
Andreas
3
dan toList()tidak mengembalikan ArrayListatau List- itu mengembalikan Collector, yang pada akhirnya akan membuat dan mengembalikan List- juga dokumentasi menyatakan: "... Tidak ada jaminan pada jenis , mutabilitas, serializability, atau keselamatan benang dari Daftar yang dikembalikan; jika kontrol lebih besar atas Daftar yang dikembalikan diperlukan, gunakan toCollection (Pemasok) .... "
user85421-Banned
3
Saya sangat merekomendasikan dokumentasi paket
Holger

Jawaban:

18
  1. Ini implementasi standar. ArrayListdigunakan, karena yang terbaik dalam kebanyakan kasus penggunaan, tetapi jika itu tidak cocok untuk Anda, Anda selalu dapat menentukan kolektor Anda sendiri dan menyediakan pabrik untuk yang CollectionAnda inginkan:

    Arrays.stream(arr).boxed().collect(toCollection(LinkedList::new));
  2. Ya, Adan Rmerupakan parameter umum dari metode ini, Radalah tipe pengembalian, Tadalah tipe input dan Amerupakan tipe perantara, yang muncul di seluruh proses pengumpulan elemen (mungkin tidak terlihat dan tidak terkait fungsi ini). Awal Collectorjavadoc mendefinisikan tipe-tipe tersebut (mereka konsisten di seluruh dokumen):

    T - jenis elemen input ke operasi reduksi
    A - tipe akumulasi yang bisa berubah dari operasi reduksi (sering disembunyikan sebagai detail implementasi)
    R - tipe hasil operasi reduksi

Andronicus
sumber
Ok aku paham. Saya kira saya harus benar-benar berpegang pada List<Integer> myList = Arrays.stream(arr).boxed().collect(Collectors.toList());dan memanggil hanya metode yang dideklarasikan di Daftar antarmuka pada myList. Kalau tidak, saya berpotensi menempatkan diri saya dalam risiko, jika Oracle memutuskan untuk mengubah implementasi default di Java8u1024 atau 15?
user3207158
2
@ user3207158 metode mengembalikan a List, jadi implementasi apa pun yang digunakan, perilaku adalah sama. Sepertinya antarmuka tidak akan diubah dalam versi java yang lebih baru.
Andronicus
1
  1. Mengapa Collectors.toList () dalam hal ini mengembalikan antarmuka Daftar implementasi ArrayList?

Sebagai definisi metode menyarankan itu mengembalikan implementasi Kolektor dengan pemasok kolektor sebagai ArrayList. Oleh karena itu, sangat jelas dari definisi metode di bawah ini yang Collectors.toListselalu mengembalikan kolektor ArrayList ( While it's arguable why toList not toArrayList word is used in method name).

public static <T>
    Collector<T, ?, List<T>> toList() {
        return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
                                   (left, right) -> { left.addAll(right); return left; },
                                   CH_ID);
    }
  1. Apa artinya panel kiri <R, A> R collect(Collector<? super T, A, R> collector)artinya

Jika Anda merujuk pada komentar dokumentasi, maka secara akurat menyebutkan jenis generik ini:

/*
      @param <R> the type of the result
      @param <A> the intermediate accumulation type of the {@code Collector}
      @param collector the {@code Collector} describing the reduction
      @return the result of the reduction
*/
 <R, A> R collect(Collector<? super T, A, R> collector);
Vinay Prajapati
sumber
Terima kasih Pak. Di mana Anda mendapatkan kode sumber Collectors.toList()(cuplikan pertama)? Apakah itu openjdk?
user3207158
1
Tidak! Saya telah mengunduh kode sumber di intelli j
Vinay Prajapati