2017-05-05 47 views

回答

2

您正在查找的是Streammap()功能。

例如:

List<String> strings = stream 
.map(Object::toString) 
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll); 
+0

如果我使用地图,我将不得不使用多行。像myStream.map(obj - > {obj.foo(); return obj;})。我想知道是否有单线解决方案。 – alexgbelov

+0

你也可以参考一个方法,检查我的mod。 – csenga

0

我认为你正在寻找Stream.peek。但仔细阅读文档,因为它主要是作为调试方法设计的。从文档:

这种方法主要存在于支持调试,您希望看到的内容,因为他们流过一定点在管道

传递给peek行动应该成为non interfering

1

不完全知道你的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

5

有(至少)3种方法。对于示例代码起见,我假设你要调用2种消费方式methodAmethodB

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);}); 

这是最灵活的,可能不适合您的需要。

+0

在'map'的函数中使用副作用并使用'peek'来实现这种(非调试)副作用的影响基本相同。 – Holger

+0

@Holger谁说副作用? – Bohemian

+0

'method1(x);'的调用完全没用,如果没有副作用的话。 – Holger

0

您拥有的最佳选择是将地图应用于您的信息流。它返回由施加给定的,功能此流的例如元件的结果的流:

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; 
}