Подтвердить что ты не робот

Реализация Collection.stream()

Я работаю над JDK 1.8 в течение нескольких дней, когда я наткнулся на какой-то фрагмент кода, который был похож на это:

List<Integer> list = Arrays.asList(1,2,3,4,5);
list.stream();

Теперь, простой и чистый, как это может показаться людям, которые работали с потоками (java.util.stream), я не смог найти фактический класс, который реализует метод java.util.Collection.stream().

У меня есть следующие вопросы, когда я говорю list.stream():

  • Где я могу получить java.util.stream.Stream от?
  • Как они реализовали его, фактически не "нарушив" существующие коллекции? (предполагая, что они их не трогали).

Я попытался просмотреть документацию java.util.AbstractCollection и java.util.AbstractList, но не смог его найти.

4b9b3361

Ответ 1

Java 8 позволяет определять методы по умолчанию в интерфейсах.

Collection<E>, тогда определяет:

default Stream<E> stream() {
    return StreamSupport.stream(spliterator(), false);
}

Как они это добавили.

Ответ 2

Как отмечали другие, метод .stream() реализован как метод по умолчанию в интерфейсе Collection, как вы можете видеть это в сигнатуре метода в официальной документации :

default Stream<E> stream()

Как реализован интерфейс потока, является деталью реализации коллекции. Однако реализация одного и того же тяжелого интерфейса Stream для каждой коллекции будет большой работой и дублированием, поэтому они используют промежуточную абстракцию, называемую Spliterator.

Этот SO-поток на .stream() может быть также полезен.

Ответ 3

Это метод по умолчанию (еще одна функция Java 8) в определении интерфейса коллекции. См. Collection.java Line 580 для кода:

default Stream<E> stream() {
   return StreamSupport.stream(spliterator(), false);
}

Ответ 4

Вы не видели его в ArrayList, потому что он определен в Collection как метод по умолчанию (вы, вероятно, уже это получили). Но это можно было бы определить в ArrayList или любой другой коллекции, тем самым переопределяя ее. Например, он определен в CopiesList как:

    @Override
    public Stream<E> stream() {
        return IntStream.range(0, n).mapToObj(i -> element);
    }

Таким образом, переопределяя один из Collection; это означает, что это не всегда один из суперкласса.