首页 > 解决方案 > 在中间操作中使用收集的结果可能会出现什么问题?

问题描述

考虑以下场景,其中一个中间操作关心之前的哪个操作成功。

// isSelected -> method that returns a boolean on whether the current source is selected
List<String> selectedSources = new ArrayList<>();
sources.stream()
    .map(source -> Pair.of(source, isSelected(source, selectedSources)))
    .filter(pair -> pair.isRight())
    .map(pair -> pair.getLeft())
    .collect(Collectors.toCollection(() -> selectedSources));

在这种情况下,我们并没有真正发挥作用,我们在其中一个中间步骤中使用终端收集的结果。这可行,但违背了 java 流的一些基本原则,以及一般的函数式编程。是否有关于这是否是良好做法或是否应该避免的一般指导?

标签: javajava-8java-stream

解决方案


通常.collect与现有集合一起使用不是一个好习惯。通常你应该收集到一个新的集合中。

尽管如果您仍想修改现有集合(这可能会导致并发问题),您可以.forEach改用:

List<String> selectedSources = new ArrayList<>();
sources.stream()
       .filter(source -> isSelected(source, selectedSources))
       .forEach(selectedSources::add);

由于您正在编写修改现有集合的“非真正功能”Stream API代码,因此没有理由在此处强制使用方法。

恕我直言,增强的 for 循环和嵌套的 if 语句在您的情况下可以做得很好。代码更具可读性:

List<String> selectedSources = new ArrayList<>();
for (String source : sources) {
    if (isSelected(source, selectedSources)) {
        selectedSources.add(source);
    }
}

推荐阅读