Java 使用 map 流式检查多次调用的结果

Java stream check results of multiple calls using map

关于正确使用流和映射,我有以下问题。

问题如下

我有一个从输入中读取文件并将记录插入数据库的方法,简而言之,它执行了一些副作用

此外,同一个函数 return 是某种状态,比方说一个布尔值(我对此有一定的自由度),表明函数运行良好。

public static boolean execute(String filename){

    // Perform some side effects (e.g. write on DB)

    return true; // or false according to some criteria;

}

然后,我必须用比方说两个文件来调用它,并且我必须检测是否至少有一个运行良好(即,如果至少有一个执行 returned true)

我的简单解决方案是:(一种简化版的命令模式)

public class Entrypoint {

    public static boolean myFunction(String input) {
        System.out.println("executed..." + input);
        return !input.equals("B");
    }

    public static void main(String[] args) {

        List<String> lst = Arrays.asList("A", "B", "C", "D", "E", "F");

        long callsOk = lst.stream().map(Entrypoint::myFunction)
            // .filter(x -> x.equals(true)).count();
            .filter(x -> x).count(); // Better, as suggested by Donat

        System.out.println("OK=" + callsOk);

    }
}

这项工作很好,输出是:

executed...A
executed...B
executed...C
executed...D
executed...E
executed...F
OK=5

这是正确的,因为对于“B”它应该失败(return false)

问题是:

是否可以使用像 myFunction 这样的函数:

在地图中计算产量 == true?

还是我搞砸了,有更好的解决方案来处理这个问题吗?

有两个答案。

首先:是的,它有效。你可以这样做。

第二:不要这样做!流用于函数式编程,函数式编程是为了避免副作用。这是一种误用,可能会造成混淆。考虑更复杂的情况!熟悉函数式编程的人可能不会想到这种误用。

这意味着:如果您的命令式代码具有副作用或有状态操作,则不应使用流。在这种情况下,经典的 for each 循环是更好的选择。这是风格问题。在许多情况下(比如这个),使用流的解决方案运行良好,但它的风格很糟糕。

另一个问题:当你避免流中的副作用时,你可以轻松地将它们更改为并行执行。

顺便说一下,filter(x -> x.equals(true))可以简化为filter(x -> x)