Как toArray(Foo[]::new) работает в потоках Java?

Так что это хорошо компилируется:

import java.util.stream.Stream;

class Foo {
    void foo() {
        Object[] foo = Stream.of(new Foo()).toArray();
    }
}

но я не хочу Object[], Я хочу Foo[]Итак, вот мой первый дубль:

import java.util.stream.Stream;

class Foo {
    void foo() {
        Foo[] foo = Stream.of(new Foo()).toArray(Foo[]::new);
    }
}

который также хорошо компилируется.

Но я не хочу использовать ссылки на методы, я нахожу их слишком запутанными, и так как я знаком с Foo[] foos = Arrays.asList(new Foo()).toArray(new Foo[1]);, Я попробую:

import java.util.stream.Stream;

class Foo {
    void foo() {
        Foo[] foo = Stream.of(new Foo()).toArray(new Foo[1]);
    }
}

и когда я пытаюсь скомпилировать это, я получаю:

Foo.java:5: error: method toArray in interface Stream<T> cannot be applied to given types;
        Foo[] foo = Stream.of(new Foo()).toArray(new Foo[1]);
                                        ^
  required: IntFunction<A[]>
  found: Foo[]

В интерфейсе Stream есть 2 метода toArray(): toArray() и toArray (IntFunction). И да конечно new Foo[1] не относится к IntFunction<A[]> но это так для Foo::new тоже не так ли?

Как обычно, я что-то здесь упускаю, что это? Как так Foo::new компилирует нормально здесь?

2 ответа

Решение
Foo[]::new

не является массивом Foo. Так что это не эквивалентно new Foo[1], Это ссылка на конструктор Foo[] учебный класс. Так что это функция (IntFunction<Foo[]> чтобы быть точным), который, когда вызывается, создает Foo[] вызывая его конструктор. Таким образом, это эквивалентно

(int size) -> new Foo[size]

Как вы предположили, вы используете toArray(IntFunction) перегрузки. Foo[]::new компилируется в нечто подобное

IntFunction<Foo> generator = (int size) -> new Foo[size];

Другими словами, IntFunction создает массив с размером Stream который Stream затем можно использовать, чтобы заполнить его Foo экземпляров.

Javadoc объясняет это

Возвращает массив, содержащий элементы этого потока, используя предоставленную функцию генератора для выделения возвращаемого массива, а также любые дополнительные массивы, которые могут потребоваться для секционированного выполнения или для изменения размера.

Ссылка на конструктор массива удовлетворяет такой функции генератора.

Другие вопросы по тегам