Fra*_*sco 9 java builder java-8 java-stream
我正在使用一个简单的循环构建一个对象:
WebTarget target = getClient().target(u);
for (Entry<String, String> queryParam : queryParams.entrySet()) {
target = target.queryParam(queryParam.getKey(), queryParam.getValue());
}
Run Code Online (Sandbox Code Playgroud)
我想使用Java8 Stream API做同样的事情,但我无法弄清楚如何做到这一点.让我挣扎的是每次都重新分配目标,所以简单的.forEach()将不起作用.我想我需要使用.collect()或reduce(),因为我正在寻找单个返回值,但此刻我迷路了!
Tag*_*eev 11
实现foldLeftJava 8流的正确性并不是很困难:
@SuppressWarnings("unchecked")
public static <T, U> U foldLeft(Stream<T> stream,
U identity, BiFunction<U, ? super T, U> accumulator) {
Object[] result = new Object[] { identity };
stream.forEachOrdered(t -> result[0] = accumulator.apply((U) result[0], t));
return (U) result[0];
}
Run Code Online (Sandbox Code Playgroud)
或者以类型安全的方式:
public static <T, U> U foldLeft(Stream<T> stream,
U identity, BiFunction<U, ? super T, U> accumulator) {
class Box {
U value;
Box(U value) { this.value = value; }
}
Box result = new Box(identity);
stream.forEachOrdered(t -> result.value = accumulator.apply(result.value, t));
return result.value;
}
Run Code Online (Sandbox Code Playgroud)
这适用于顺序和并行流.如果您的流具有一些消耗CPU的无状态中间操作,您甚至可以使用并行流来获得速度增益map:在这种情况下,下一个元素可以与处理map的当前元素并行处理foldLeft.我不同意这种操作不适合Stream API,因为它可以通过已经存在的方式正确表达forEachOrdered.
我在我的StreamEx库中有这个操作,所以你可以像这样使用它:
WebTarget target = EntryStream.of(queryParams).foldLeft(getClient().target(u),
(t, entry) -> t.queryParam(entry.getKey(), entry.getValue()))
Run Code Online (Sandbox Code Playgroud)
遗憾的foldLeft是,流API中没有方法.Stuart Marks在这个答案中解释了这个原因:
[...]最后,Java不提供
foldLeft和foldRight操作,因为它们意味着特定的操作顺序本质上是顺序的.这与上述设计原则相冲突,即提供支持顺序和并行操作的API.
最终你在这里尝试做的是程序/顺序,所以我不认为流API非常适合这个用例.我认为你自己发布的for-each循环就像它得到的一样好.
更新:
作为@TagirValeev指出下面你可以实际上与流API解决这个问题(使用forEachOrdered.然后,您的代码会看起来像
WebTarget[] arr = { getClient().target(u) };
queryParams.entrySet()
.stream()
.forEachOrdered(e -> arr[0] = arr[0].queryParam(e.getKey(),
e.getValue()));
WebTarget target = arr[0];
Run Code Online (Sandbox Code Playgroud)
我支持我的原始答案,并声称在这种情况下,你的旧的for-loop是一种更好的方法.
| 归档时间: |
|
| 查看次数: |
4350 次 |
| 最近记录: |