Зачем перегружать метод varargs () в интерфейсе Java Stream?
Интерфейс Stream имеет две перегрузки для метода of()
, Одним из них является метод переменной-арности, в то время как другой принимает один аргумент.
Является ли метод с одним аргументом оптимизацией производительности по сравнению с передачей одного аргумента в метод переменной-арности? Если так, как это улучшает производительность? Те же вопросы можно задать empty()
метод, который может показаться синтаксическим сахаром вокруг переменной арности of()
,
Я вижу, что реализация отличается между этими методами, с разницей, очевидно, в том, как Spliterator
инстанцируется; но какое преимущество это дает Stream
API?
3 ответа
Да, это оптимизация, позволяющая избежать накладных расходов на создание массива, содержащего только один элемент, который вы получите, если используете версию varargs.
Те же вопросы можно задать для метода empty(), который может показаться синтаксическим сахаром для переменной-арности ()
На какую версию реализации вы смотрите? Когда я смотрю на реализацию, я не вижу этого.
Пустой поток и поток одного элемента являются очень распространенными случаями использования, особенно когда вы используете .flatMap()
, Например, вот как Optional.stream()
реализован в Java-9:
public Stream<T> stream() {
if (!isPresent()) {
return Stream.empty();
} else {
return Stream.of(value);
}
}
Поэтому, учитывая поток опциональных файлов, вы можете развернуть их в плоский поток следующим образом:
streamOfOptionals.flatMap(Optional::stream);
Здесь вы создаете тонны пустых потоков, а также потоков из одного элемента, поэтому оптимизация таких случаев выглядит очень разумной. Особенно, Stream.empty()
В отличие от Stream.of()
не создает пустой массив и не создает разделитель (он использует тот же экземпляр разделителя). Stream.of(T)
также особенно оптимизирован внутри StreamBuilderImpl
, так что никакой массив не выделяется для одного элемента.
Я наткнулся на официальный ресурс, который подтверждает предыдущие ответы на этот вопрос: JEP 269: методы фабрики удобства для коллекций. Описание этого предложения
Предоставить статические фабричные методы на
List
,Set
, а такжеMap
интерфейсы для создания неизменяемых экземпляров этих коллекций.Они будут включать в себя перегрузки varargs, так что нет фиксированного ограничения на размер коллекции... Будут предоставлены специальные API-интерфейсы (перегрузки с фиксированным аргументом) для до десяти элементов. Хотя это вносит некоторую путаницу в API, оно позволяет избежать выделения массивов, инициализации и издержек на сборку мусора, возникающих при вызовах varargs.
Таким образом, оптимизация производительности довольно проста, чтобы избежать использования массива метода varargs.