地图是否在过滤器 findAny 之前应用于所有列表?
Is map applied on all the list before filter findAny?
我想过滤列表中具有非 null 属性 的元素并返回 属性:
list.stream.map(a -> StringUtils.trimToEmpty(a.getProp())).filter( p -> StringUtils.isNotEmpty(p)).findAny().orElse("");
上面的代码是否先映射了所有元素?出于效率原因,我想逐个元素地处理。
Stream::findAny
is a short-circuiting terminal operation,简而言之,如果输入是,它会终止 Stream。
即。如果第一个元素符合 Stream::filter
管道的条件并通过它,Stream::findAny
returns 它会立即不处理原始集合中的其他元素。
有一个使用 Stream::peek
的很好的证明来理解 Stream API 是如何工作的(假设 class Foo
只有一个最终字符串参数 prop
):
List<Foo> list = List.of(
new Foo(""), // the first is empty and doesn't pass through Stream::filter
new Foo("one"), // this is qualified
new Foo("two")); // this is qualified
list.stream()
.peek(item -> System.out.println("# Streamed " + item.getProp())) // streamed
.map(a -> StringUtils.trimToEmpty(a.getProp()))
.peek(item -> System.out.println("# Mapped " + item)) // mapped
.filter(StringUtils::isNotEmpty)
.peek(item -> System.out.println("# Filtered " + item)) // filtered
.findAny()
.orElse("");
输出显示第一个元素没有通过 Stream::filter
(为空)并在 Stream::map
之前结束。第二个元素经过Stream::filter
和随后的Stream::map
,最后到达Stream::findAny
。只要 Stream::findAny
是具有当前结果的短路和终止操作,它就会终止 Stream。
# Streamed
# Mapped
# Streamed one
# Mapped one
# Filtered one
我想过滤列表中具有非 null 属性 的元素并返回 属性:
list.stream.map(a -> StringUtils.trimToEmpty(a.getProp())).filter( p -> StringUtils.isNotEmpty(p)).findAny().orElse("");
上面的代码是否先映射了所有元素?出于效率原因,我想逐个元素地处理。
Stream::findAny
is a short-circuiting terminal operation,简而言之,如果输入是,它会终止 Stream。
即。如果第一个元素符合 Stream::filter
管道的条件并通过它,Stream::findAny
returns 它会立即不处理原始集合中的其他元素。
有一个使用 Stream::peek
的很好的证明来理解 Stream API 是如何工作的(假设 class Foo
只有一个最终字符串参数 prop
):
List<Foo> list = List.of(
new Foo(""), // the first is empty and doesn't pass through Stream::filter
new Foo("one"), // this is qualified
new Foo("two")); // this is qualified
list.stream()
.peek(item -> System.out.println("# Streamed " + item.getProp())) // streamed
.map(a -> StringUtils.trimToEmpty(a.getProp()))
.peek(item -> System.out.println("# Mapped " + item)) // mapped
.filter(StringUtils::isNotEmpty)
.peek(item -> System.out.println("# Filtered " + item)) // filtered
.findAny()
.orElse("");
输出显示第一个元素没有通过 Stream::filter
(为空)并在 Stream::map
之前结束。第二个元素经过Stream::filter
和随后的Stream::map
,最后到达Stream::findAny
。只要 Stream::findAny
是具有当前结果的短路和终止操作,它就会终止 Stream。
# Streamed
# Mapped
# Streamed one
# Mapped one
# Filtered one