Поток.метод peek () в Java 8 против Java 9
Я нахожусь в процессе обучения с помощью Java 8 лямбда-выражений и хотел бы спросить о следующем фрагменте кода Java, относящемся к peek метод в интерфейсе функции, с которым я столкнулся.
при выполнении программы на IDE, он не дает никакого результата. Я ожидал, что это даст 2, 4, 6.
import java.util.Arrays;
import java.util.List;
public class Test_Q3 {
public Test_Q3() {
}
public static void main(String[] args) {
List<Integer> values = Arrays.asList(1, 2, 3);
values.stream()
.map(n -> n * 2)
.peek(System.out::print)
.count();
}
}
2 ответа:
Я предполагаю, что вы используете это под Java 9? Вы не изменяете
SIZEDсвойства потока, поэтому нет необходимости выполнять либоmapилиpeekна всех.другими словами, все, что вас волнует
countкак конечный результат, но в то же время вы не изменяете начальный размерListна любой способом (через илиdistinct) это оптимизация, выполненная в потоках.кстати, даже если вы добавляете манекен фильтр это покажет, что вы ожидаете:
values.stream () .map(n -> n*2) .peek(System.out::print) .filter(x -> true) .count();
вот некоторые соответствующие цитаты из Javadoc из поток интерфейс:
реализация потока допускает значительную широту в оптимизации вычисления результата. Например, реализация потока свободна от операций elide (или целых этапов) из конвейера потока-и, следовательно, вызов elide поведенческих параметров-если он может доказать, что это не повлияет на результат вычисления. Это означает, что побочные эффекты поведенческих параметров не всегда могут быть выполнены и не следует полагаться, если не указано иное (например, терминальные операции forEach и forEachOrdered). (Конкретный пример такой оптимизации см. В примечании API, описанном в операции count (). Дополнительные сведения см. В разделе побочные эффекты документации по пакету stream.)
и более конкретно из Javadoc из count () метод:
API Примечание:
реализация может не выполнять конвейер потока (либо последовательно, либо параллельно), если она способна вычислять количество непосредственно из источника потока. В таких случаях никакие исходные элементы не будут пройдены и никакие промежуточные операции не будут оцениваться. Поведенческие параметры с побочными эффектами, которые сильно обескуражены за исключением безвредных случаев как отладка, может быть затронута. Например, рассмотрим следующий поток:
List<String> l = Arrays.asList("A", "B", "C", "D"); long count = l.stream().peek(System.out::println).count();количество элементов, охватываемых источником потока, списком, известно, и промежуточная операция, peek, не вводит и не удаляет элементы из потока (как это может быть в случае операций flatMap или filter). Таким образом, счетчик-это размер списка, и нет необходимости выполнять конвейер и, как побочный эффект, распечатывать элементы списка.
эти цитаты только появляются на Javadoc Java 9, так что это должна быть новая оптимизация.