Java流检查多个调用的结果,使用map

huangapple go评论73阅读模式
英文:

Java stream check results of multiple calls using map

问题

我有关于正确使用流(streams)和映射(map)的以下问题。

问题如下:

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

此外,相同的函数会返回某种状态,假设一个布尔值(在此我有一定的自由),表示函数的执行情况如何。

public static boolean execute(String filename){

    // 执行一些副作用(例如在数据库中写入)

    return true; // 或根据某些条件返回false;

}

然后,我必须使用比方说两个文件来调用它,并且我必须检测是否至少有一个执行成功(即至少有一个执行返回true)。

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

public class Entrypoint {

    public static boolean myFunction(String input) {
        System.out.println("执行..." + 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(); // 更好,如Donat所建议

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

    }
}

这可以正常工作,输出为:

执行...A
执行...B
执行...C
执行...D
执行...E
执行...F
OK=5

这是正确的,因为对于 "B" 应该失败(返回 false)。

问题是:

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

  • 其主要目的是执行副作用,以及

  • 其返回值的目的只是为了提供操作的状态(成功与否),而不是其他任何类型的数据

在映射中以便计算 true 的数量?

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

英文:

I have the following problem regarding the correct use of streams and map.

The problem is the following

I have a method that reads a file from input and inserts record in a database, in a few words it performs some side effects

Furthermore, the same function returns some sort of a state, let's say a boolean (I have some degree of freedom about this) that states that the function went well.

public static boolean execute(String filename){

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

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

}

Then, I have to call it with let's say two files and I have to detect if at least one went well (i.e. if at least one execution returned true)

My simple solution is: (a sort of simplified version of the command pattern)

public class Entrypoint {

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

    public static void main(String[] args) {

        List&lt;String&gt; lst = Arrays.asList(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;, &quot;E&quot;, &quot;F&quot;);

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

        System.out.println(&quot;OK=&quot; + callsOk);

    }
}

This work, fine, the output is:

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

That is right because it should fail (return false) for "B"

The question is:

Is it fine to use a function like myFunction:

  • whose prime purpose is to perform side effects

and

  • the purpose of its return value is just to give the status of the operation performed (success or not) and no other kind of data

inside a map in order to count the number of yields == true?

Or am I messing up, and there is a better solution to handle this?

答案1

得分: 2

有两个答案。

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

第二:不要这样做!流(Streams)用于函数式编程,而函数式编程是关于避免副作用的。这有点滥用,会让人感到困惑。想想更复杂的情况!熟悉函数式编程的人可能不会期望出现这种滥用。

这意味着:如果你的代码具有副作用或状态操作,就不应该使用流(Streams)。在这种情况下,传统的 for-each 循环是更好的选择。这是一种风格问题。在许多情况下(比如这个例子),使用流的解决方案效果很好,但这是不好的编程风格。

另一个问题:当你在流中避免副作用时,可以很容易地将它们改成并行执行。

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

英文:

There are two answers.

First: Yes, it works. You can do it like this.

Second: Do not do this! Streams are for functional programming and functional programming is about avoiding side effects. This is kind of a misuse and it can be confusing. Think about more complicated cases! Someone familiar with functional programming will probably not expect this misuse.

This means: You should not use streams if you have imperative code with side effects or stateful operations. In this case a classical for each loop is the better choice. This is a matter of style. In many cases (like this one) the solution with streams is working well, but it is bad style.

Another issue: When you avoid side effects in streams, you can easily change them to parallel execution.

By the way, filter(x -&gt; x.equals(true)) can be simplified to filter(x -&gt; x).

huangapple
  • 本文由 发表于 2020年8月19日 03:33:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/63475501.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定