Java 8嵌套流:在最后一个流中返回一个值

Dap*_*gma 5 java lambda java-8 java-stream

可以将此问题视为基于java 8嵌套流

假设我有一个BatchBaskets的ItemS:

public class Batch {
    private List<Basket> baskets;
}

public class Basket {
    private List<Item> items; 
}

public class Item {
    private String property;
    private int value;
}
Run Code Online (Sandbox Code Playgroud)

我想用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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我该怎么办?

我想去的第一步:

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'
    }
}
Run Code Online (Sandbox Code Playgroud)

非常感谢.

小智 6

baskets.stream()
            .flatMap(basket -> basket.getItems().stream())
            .filter(item -> item.equals("someValue"))
            .findAny()
            .orElseThrow(NoSuchElementException::new);
Run Code Online (Sandbox Code Playgroud)

使用findAny代替的优点findFirstfindFirst不适用于并行流。因此,如果要并行执行上述操作,则只需将stream()方法替换为parallel()


Ant*_*ond 5

  1. 使用flatMap得到嵌套列表的顺风车,提取每个List<Item>并将它们合并成一个Stream<Item>,它就像所有子合并在一起。
  2. 使用filter忽略不匹配元素。
  3. 用于findFirst仅获取第一次出现并停止处理
  4. 用于orElseThrow在未找到someValue 时抛出异常。

干得好

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"));
    }
}
Run Code Online (Sandbox Code Playgroud)