Поток.метод 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, поэтому это должна быть новая оптимизация.