Як зрозуміти цей метод Java 8 Stream collection ()?


12

Я намагався перетворити масив int в List, і я взяв незнайомий маршрут використання Java 8 Stream і придумав це

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

У мене все ще є труднощі повністю зрозуміти цю лінію, в основному,

  1. Чому Collectors.toList()в цьому випадку повертається інтерфейс ArrayList<Integer>реалізації List? Чому ні LinkedList<Integer>чи будь-який інший загальний клас, що відповідає Listінтерфейсу? Я нічого не можу знайти про це, крім короткої згадки про ArrayList тут , у розділі API Notes.

  2. Що означає ліва панель ? Очевидно, це загальний тип повернення ( у моєму коді тут). Я думаю, що це аргумент загального типу методу, але як вони вказані? Я заглянув у doc інтерфейс колектора і не зміг його засвоїти.введіть тут опис зображення Stream.collect()RArrayList<Integer><R, A>


2
1. Воно, очевидно, використовує фактичний список під кришкою. Але API було б нерозумно розкривати фактичний тип списку. З тих пір вони більше не могли змінити реалізацію в майбутньому. Взагалі, часто корисно розкривати інтерфейси, а не фактичний базовий тип. 2. R- це родовий тип отриманого типу. Aзагальний тип проміжного типу накопичення колектора. Це детальна інформація про те, як працює колектор. Він розділяє і перемагає, також для паралельної обробки, збирає спочатку в проміжні типи.
Забузард

10
Ви майже ніколи не хочете LinkedList. Є твіт Джоша Блоха , який говорить: "Я написав це, і ніколи його не використовую".
Енді Тернер

4
"Чому Collectors.toList()в цьому випадку повертає ArrayList<Integer>" Можливо, він не поверне ArrayList. ListРеалізація НЕ визначена , так що ви не можете покладатися на те , що реалізація повертається. Як говорить javadoc : " Жодних гарантій щодо типу , змінності, серіалізаційності або безпеки потоку повернених списків немає".
Андреас

3
і toList()не повертає ArrayListабо List- це повернення a Collector, яке в підсумку створить і поверне a List- також у документації зазначено: "... немає гарантій щодо типу , змінності, серіалізаційності або безпеки потоку поверненого списку; якщо потрібен більше контроль над поверненим Списком, використовуйте toCollection (постачальник) .... "
user85421-Заборонено

3
Я настійно рекомендую пакетну документацію
Holger

Відповіді:


18
  1. Це реалізація за замовчуванням. ArrayListвикористовується, тому що найкраще в більшості випадків використання, але якщо це не підходить для вас, ви завжди можете визначити власний колектор і надати фабрику за Collectionвашим бажанням:

    Arrays.stream(arr).boxed().collect(toCollection(LinkedList::new));
  2. Так, Aі Rє загальні параметри цього методу, Rце тип повернення, Tце тип введення і Aє проміжним типом, який з'являється у всьому процесі збирання елементів (може бути не видно і не стосується цієї функції). Початок Collector«javadoc» визначає ці типи (вони відповідають всій документації):

    T - тип вхідних елементів в операцію скорочення
    A - тип накопичуваного накопичення операції скорочення (часто прихований як деталь реалізації)
    R - результат результату операції скорочення


Добре, я бачу. Я думаю, я повинен дійсно дотримуватися List<Integer> myList = Arrays.stream(arr).boxed().collect(Collectors.toList());і викликати лише методи, оголошені в інтерфейсі List на myList. В іншому випадку я б потенційно піддав себе ризику, якщо Oracle вирішить змінити реалізацію за замовчуванням у Java8u1024 або 15?
user3207158

2
@ user3207158 метод повертає a List, так що будь-яка реалізація використовується, поведінка однакова. Навряд чи інтерфейс буде змінено в новіших версіях Java.
Андронік

1
  1. Чому в цьому випадку Collectors.toList () повертає інтерфейс списку реалізації ArrayList?

Як показує визначення методу, він повертає реалізацію Collector разом з постачальником колектора як ArrayList. Отже, із визначення нижче методу зрозуміло, що Collectors.toListArrayList завжди повертає колектор ( 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. Що означає ліва панель <R, A> R collect(Collector<? super T, A, R> collector)засобів

Якщо ви посилаєтесь на коментарі до документації, в ній точно зазначено, що це за типові типи:

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

Дякую вам сер. Звідки ви взяли вихідний код Collectors.toList()(перший фрагмент)? Це openjdk?
користувач3207158

1
Ні! Я завантажив вихідний код у моїй програмі Intelli j
Vinay Prajapati
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.