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

Ett*_*lli 5 java command-pattern java-8 java-stream

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

问题如下

我有一种方法可以从输入中读取文件并将记录插入数据库中,简而言之,它会产生一些副作用

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

public static boolean execute(String filename){

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

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

}
Run Code Online (Sandbox Code Playgroud)

然后,我必须用两个文件来调用它,我必须检测至少一个文件是否运行良好(即,如果至少一个执行返回 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);

    }
}
Run Code Online (Sandbox Code Playgroud)

这项工作,很好,输出是:

executed...A
executed...B
executed...C
executed...D
executed...E
executed...F
OK=5
Run Code Online (Sandbox Code Playgroud)

这是正确的,因为它应该为“B”失败(返回 false)

问题是:

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

  • 其主要目的是产生副作用

  • 它的返回值的目的只是给出所执行操作的状态(成功与否)而不是其他类型的数据

在地图内以计算产量 == 真的数量?

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

Don*_*nat 2

有两个答案。

第一:是的,它有效。你可以这样做。

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

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

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

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