有时在处理Java流()时,我发现自己需要使用非终端forEach()来触发副作用,但不会终止处理.
我怀疑我可以使用类似.map(item - > f(item))的方法执行此操作,其中方法f执行副作用并将项目返回到流,但它似乎有点笨拙.
有没有一种标准的处理方式?
Tho*_*ger 14
就在这里.它被称为peek()(来自JavaDoc的示例):
Stream.of("one", "two", "three", "four")
.peek(e -> System.out.println("Original value: " + e))
.filter(e -> e.length() > 3)
.peek(e -> System.out.println("Filtered value: " + e))
.map(String::toUpperCase)
.peek(e -> System.out.println("Mapped value: " + e))
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
Mat*_*ead 10
不,那里没有。
peek()仅在被以下操作强制时对所有元素进行操作。你能预测这段代码会打印什么吗?
public class Test
{
private static final AtomicBoolean FLAG = new AtomicBoolean(false);
private static void setFlagIfGreaterThanZero(int val)
{
if (val > 0) {
FLAG.set(true);
}
}
public static void main(String[] args)
{
FLAG.set(false);
// Test 1
IntStream.range(0, 10)
.peek(Test::setFlagIfGreaterThanZero)
.findFirst();
System.out.println(FLAG.get());
FLAG.set(false);
// Test 2
IntStream.range(0, 10)
.peek(Test::setFlagIfGreaterThanZero)
.sorted()
.findFirst();
System.out.println(FLAG.get());
FLAG.set(false);
// Test 3
IntStream.range(0, 10)
.boxed()
.peek(Test::setFlagIfGreaterThanZero)
.sorted()
.findFirst();
System.out.println(FLAG.get());
FLAG.set(false);
// Test 4
IntStream.range(0, 10)
.peek(Test::setFlagIfGreaterThanZero)
.filter(x -> x == 0)
.toArray();
System.out.println(FLAG.get());
}
}
Run Code Online (Sandbox Code Playgroud)
答案是:
假
假
真
真
如果你有Java流有扎实的理解这输出可能是直观的,但希望它也预示着这是一个非常糟糕的主意依靠peek()作为中游forEach()。
map()也遇到同样的问题。据我所知,没有 Stream 操作可以保证在每种情况下都独立于先前和后续操作的“处理每个元素而不走捷径”行为。
尽管这可能很痛苦,但 Streams 的短路行为是一个重要特性。您可能会发现这个出色的答案很有用:https : //stackoverflow.com/a/32194320/507761
| 归档时间: |
|
| 查看次数: |
2996 次 |
| 最近记录: |