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 Batchwith Baskets with Items :
假设我有一个Batchwith Baskets with Items :
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 findAnyinstead of findFirstis that findFirstdoesn'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
flatMapto get ride of nested lists, extract eachList<Item>and merge them into aStream<Item>, it acts like all substream were merged together. - Use
filterto ignore the non matching elements. - Use
findFirstto get the first occurence only and stop processing - Use
orElseThrowto 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 flatMapto produce a Stream<Item>of all the Items of all the Baskets :
要消除这两个循环,您可以使用flatMap生成Stream<Item>所有Items 的所有Baskets 的 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

