Java 8 嵌套流:在最后一个流中返回一个值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43498884/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java 8 nested streams : return a value in last stream
提问by Dapangma
This question can be considered as based on java 8 nested streams
这个问题可以被认为是基于java 8 嵌套流
Suppose I have a Batch
with Basket
s with Item
s :
假设我有一个Batch
with Basket
s with Item
s :
public class Batch {
private List<Basket> baskets;
}
public class Basket {
private List<Item> items;
}
public class Item {
private String property;
private int value;
}
I would like to rewrite this method with Java 8 streams.
我想用 Java 8 流重写这个方法。
public class SomeService {
public int findValueInBatch(Batch batch) {
for (Basket basket : batch.getBaskets()) {
for (Item item : basket.getItems()) {
if (item.getProperty().equals("someValue") {
return item.getValue();
}
}
}
return 0;
}
}
How should I do it ?
我该怎么做?
First step to where I'd like to go :
我想去的地方的第一步:
public int findValueInBatch(Batch batch) {
for (Basket basket : batch.getBaskets()) {
basket.getItems().stream()
.filter(item -> item.getProperty.equals("someValue")
.findFirst()
.get();
// there I should 'break'
}
}
Thanks a lot.
非常感谢。
回答by Avneet Paul
baskets.stream()
.flatMap(basket -> basket.getItems().stream())
.filter(item -> item.equals("someValue"))
.findAny()
.orElseThrow(NoSuchElementException::new);
The advantage of using findAny
instead of findFirst
is that findFirst
doesn't work with parallel streams. Therefore, if you want to parallelize the above operation all you'll need to do is replace the stream()
method with parallel()
使用findAny
而不是的优点findFirst
是findFirst
不适用于并行流。因此,如果您想并行化上述操作,您需要做的就是将stream()
方法替换为parallel()
回答by Anthony Raymond
- Use
flatMap
to get ride of nested lists, extract eachList<Item>
and merge them into aStream<Item>
, it acts like all substream were merged together. - Use
filter
to ignore the non matching elements. - Use
findFirst
to get the first occurence only and stop processing - Use
orElseThrow
to throw an exception if no occurence of someValuewere found.
- 使用
flatMap
得到嵌套列表的顺风车,提取每个List<Item>
并将它们合并成一个Stream<Item>
,它就像所有子合并在一起。 - 使用
filter
忽略不匹配元素。 - 用于
findFirst
仅获取第一次出现并停止处理 - 用于
orElseThrow
在未找到someValue 时抛出异常。
Here you go
干得好
public class SomeService {
public int findValueInBatch(Batch batch) {
return batch.getBaskets().stream()
.flatMap(basket -> basket.getItems().stream())
.filter(item -> item.getProperty.equals("someValue"))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("value not found"));
}
}
回答by Eran
To eliminate both loops you can use flatMap
to produce a Stream<Item>
of all the Item
s of all the Basket
s :
要消除这两个循环,您可以使用flatMap
生成Stream<Item>
所有Item
s 的所有Basket
s 的 a :
return batch.getBaskets()
.stream()
.flatMap(b -> b.getItems().stream())
.filter(item -> item.getProperty.equals("someValue"))
.findFirst()
.orElse(some default value); // using .get() would throw an exception
// if no match is found