此问题可视为基于java 8 nested streams
假设我Batch
Basket
与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;
}
我想用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;
}
}
我该怎么做?
我想去的第一步:
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'
}
}
非常感谢。
答案 0 :(得分:4)
baskets.stream()
.flatMap(basket -> basket.getItems().stream())
.filter(item -> item.equals("someValue"))
.findAny()
.orElseThrow(NoSuchElementException::new);
使用findAny
代替findFirst
的好处是findFirst
不适用于并行流。因此,如果您要并行执行上述操作,则需要将stream()
方法替换为parallel()
答案 1 :(得分:3)
要消除这两个循环,您可以使用flatMap
生成所有Stream<Item>
s中所有Item
的{{1}}:
Basket
答案 2 :(得分:3)
flatMap
获取嵌套列表,提取每个List<Item>
,将其转换为Stream<Item>
,并将所有子流合并在一起。filter
忽略不匹配的元素。findFirst
仅获取第一次出现并停止处理orElseThrow
抛出异常。你去吧
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"));
}
}