Java 8将函数应用于Stream的所有元素而不会破坏流链
在Java中,有没有办法将函数应用于流的所有元素而不会破坏流链?我知道我可以打电话给每个人,但是这种方法会返回一个void,而不是一个流。Java 8将函数应用于Stream的所有元素而不会破坏流链
您正在查找的是Stream
的map()
功能。
例如:
List<String> strings = stream
.map(Object::toString)
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
如果我使用地图,我将不得不使用多行。像myStream.map(obj - > {obj.foo(); return obj;})。我想知道是否有单线解决方案。 – alexgbelov
你也可以参考一个方法,检查我的mod。 – csenga
我认为你正在寻找Stream.peek
。但仔细阅读文档,因为它主要是作为调试方法设计的。从文档:
这种方法主要存在于支持调试,您希望看到的内容,因为他们流过一定点在管道
传递给peek
行动应该成为non interfering。
不完全知道你的breaking the stream chain
的意思,但在Stream
返回一个Stream
不会休息或消耗你流的任何操作。流被消耗terminal operations
,正如您注意到forEach
不会返回 a Stream<T>
并因此通过在forEach和forEach本身之前执行所有intermediate
操作来结束流。
在您在评论中提供的示例:
myStream.map(obj -> {obj.foo(); return obj;}
你不能真正做到这一点有一个衬垫。当然,你可以使用方法引用,但后来你回到Stream
将是一个不同类型的(假设foo
回报型):
myStream.map(Obj::foo) // this will turn into Stream<T>, where T is
// the return type of foo, instead of Stream<Obj>
除此之外您map
操作stateful
,这是强烈反对。你的代码将被编译,甚至可以按照你的要求工作 - 但它可能会在以后失败。 map
操作应该是stateless
。
有(至少)3种方法。对于示例代码起见,我假设你要调用2种消费方式methodA
和methodB
:
A.使用peek()
:
list.stream().peek(x -> methodA(x)).forEach(x -> methodB(x));
虽然文档说只能用它来“调试”,它的工作原理(和它的生产现在)
B.使用map()
调用了methodA,然后元素返回到流:
list.stream().map(x -> {method1(x); return x;}).forEach(x -> methodB(x));
这可能是最“可接受的”方法。
C.做两件事情在forEach()
:
list.stream().forEach(x -> {method1(x); methodB(x);});
这是最灵活的,可能不适合您的需要。
您拥有的最佳选择是将地图应用于您的信息流。它返回由施加给定的,功能此流的例如元件的结果的流:
IntStream.rangeClosed(40, 70).limit(20).mapToObj(i -> (Integer) i).map(item->item+3).map(item->item*2)...
(流类型StreamItemABC的项目)
我们正在申请若干修改到流但通过这种方式,我们不能通过任何参数来映射方法,以解决它:
private void applyMethod(ParameterX parX) {
someStreamX().map(n -> methodX(n, parX))...
}
private StreamItemABC methodX (StreamItemABC item, ParameterX parX) {
return notification;
}
您要调用的方法是否返回一个值? –
你能解释一下你的意思吗?而不打破流链?可能是一个例子? – Eugene