Bu Java 8 Stream collect () yöntemini nasıl anlayabilirim?


12

Bir int dizisini List'e dönüştürmeye çalışıyordum ve Java 8 Stream kullanmanın alışılmadık yolunu seçtim ve bununla geldim

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

Hala bu çizgiyi tam olarak anlamakta zorlanıyorum, çoğunlukla,

  1. Collectors.toList()Bu durumda neden bir ArrayList<Integer>uygulama Listarayüzü döndürülüyor ? Neden olmasın LinkedList<Integer>veya Listarayüze uygun başka bir genel sınıf ? API Notları bölümünde, burada ArrayList'ten kısaca bahsetmemek dışında, bu konuda hiçbir şey bulamıyorum .

  2. Sol panel ne anlama geliyor? Açıkçası genel dönüş türü ( benim kod burada). Bence yöntemin genel tür argümanı, ama nasıl belirtilir? Collector interface belgesine baktım ve onu ememedim.resim açıklamasını buraya girin Stream.collect()RArrayList<Integer><R, A>


2
1. Bu kesinlikle başlık altında gerçek bir liste kullanır. Ancak, bir API'nin temel Liste türünü göstermesi akıllıca olmaz. O zamandan beri gelecekte uygulamayı asla değiştiremezlerdi. Genel olarak, sadece arayüzleri ortaya çıkarmak ve altta yatan gerçek türü asla ortaya çıkarmak iyi bir fikirdir. 2. Rortaya çıkan türün genel türüdür. AToplayıcının ara birikim türünün genel türü. Bu bir toplayıcının nasıl çalıştığının uygulama detayıdır. Paralel işleme için de böler ve fetheder, ilk önce ara tiplere toplar.
Zabuzard

10
Neredeyse hiç aslında LinkedList istiyorum. Josh Bloch'un "Ben yazdım ve asla kullanmam" diyen bir tweet var .
Andy Turner

4
"Neden Collectors.toList()bu durumda dönüşlerinde bir ArrayList<Integer>" Bu bir getirmeyebilir ArrayList. ListUygulama olduğunu tanımsız , döndüğü Ne uygulanması güvenemez, böylece. Gibi javadoc diyor: "Orada türüne hiçbir garanti , mutability, serializability veya iade Listesinin parçacığı güvenliği;"
Andreas

3
ve toList()bir dönen değildir ArrayListya Listda bir dönen - Collectorsonunda oluşturmak ve dönecektir hangi bir List- de belgelerine durumları:" ... hiçbir garanti yoktur tip , mutability, serializability veya Listesinin parçacığı güvenliği döndü; Döndürülen Liste üzerinde daha fazla kontrol gerekiyorsa, toCollection (Tedarikçi) kullanın .... "
user85421-Yasaklandı

Yanıtlar:


18
  1. Bu varsayılan bir uygulamadır. ArrayListkullanılır, çünkü çoğu kullanım durumunda en iyisidir, ancak sizin için uygun değilse, her zaman kendi toplayıcınızı tanımlayabilir ve Collectionistediğiniz fabrikaya sağlayabilirsiniz :

    Arrays.stream(arr).boxed().collect(toCollection(LinkedList::new));
  2. Evet Ave Rbu yöntemin genel parametreleri olup R, dönüş tipidir, Tgiriş tipidir ve Aeleman toplama sürecinin tamamında görünen bir ara tiptir (görünür olmayabilir ve bu işlevi ilgilendirmez). Javadoc'un başlangıcıCollector bu türleri tanımlar (tüm dokümanda tutarlıdır):

    T - azaltma işlemine giriş elemanlarının türü
    A - azaltma işleminin değiştirilebilir birikim tipi (genellikle uygulama detayı olarak gizlenir)
    R - azaltma işleminin sonuç türü


Tamam anladım. Sanırım gerçekten List<Integer> myList = Arrays.stream(arr).boxed().collect(Collectors.toList());myList üzerine List arayüzünde bildirilen yöntemlere bağlı kalmalı ve çağırmalıyım. Aksi takdirde, Oracle Java8u1024 veya 15'teki varsayılan uygulamayı değiştirmeye karar verirse, kendimi risk altına sokabilirim?
user3207158

2
@ user3207158 yöntem bir döndürür List, dolayısıyla ne kullanılırsa kullanılsın, davranış aynıdır. Java'nın yeni sürümlerinde arayüzün değişmesi olası değildir.
Andronicus

1
  1. Bu durumda neden Collectors.toList () bir ArrayList uygulama Listesi arabirimi döndürür?

Yöntem tanımından da anlaşılacağı gibi, toplayıcı tedarikçisi ile birlikte bir Toplayıcı uygulaması döndürür ArrayList. Bu nedenle, aşağıdaki yöntem tanımından Collectors.toListher zaman ArrayList toplayıcı ( While it's arguable why toList not toArrayList word is used in method name) döndüren çok açıktır .

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. Sol panelin <R, A> R collect(Collector<? super T, A, R> collector)anlamı nedir

Doküman yorumlarına başvurursanız, bu genel türlerin ne olduğunu doğru bir şekilde belirtir:

/*
      @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);

Teşekkürler bayım. Collectors.toList()(İlk pasaj) kaynak kodunu nereden aldınız ? Bu openjdk mı?
user3207158

1
Hayır! Intelli j kaynak kodunu indirdim
Vinay Prajapati
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.