Как 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 объясняет это
Возвращает массив, содержащий элементы этого потока, используя предоставленную функцию генератора для выделения возвращаемого массива, а также любые дополнительные массивы, которые могут потребоваться для секционированного выполнения или для изменения размера.
Ссылка на конструктор массива удовлетворяет такой функции генератора.