有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用Java8谓词查找“最”正确值的函数式编程

谢谢你检查我的问题

我在使用以特定顺序应用多个谓词的流时遇到了一些麻烦

为了举例,请考虑下面的谓词:

        IntPredicate divisibleByThree = i -> i % 3 == 0;
        IntPredicate divisibleByFour = i -> i % 4 == 0;
        IntPredicate divisibleByFive = i -> i % 5 == 0;
        IntPredicate divisibleByThreeAndFour = divisibleByThree.and(divisibleByFour);
        IntPredicate divisibleByThreeAndFive = divisibleByThree.and(divisibleByFive);
        IntPredicate divisibleByThreeAndFiveAndFour = divisibleByThreeAndFour.and(divisibleByFive);
        //....arbitrary Number of predicates.

第一部分

我已经将我遇到的问题转化为“FizzBuzz”式的版本,试图通过将谓词按特定顺序应用于流来找到正确的答案。就像这样:

    IntStream.range(1, 100).forEach(i -> {
        //Order matters here!
        if(divisibleByThreeAndFiveAndFour.test(i)){
            System.out.println("Three and four and five");
        } else if(divisibleByThreeAndFour.test(i)){
            System.out.println("Three and four");
        } else if(divisibleByThreeAndFive.test(i)){
            System.out.println("Three and four");
        } else if(divisibleByFive.test(i)){
            System.out.println("Five");
        }
        //etc, etc.
    });

我不认为这是一个非常漂亮的代码,有没有更好的方法来实现这一点

第二部分

如果我真的需要应用谓词来查看流中是否存在适当的值,并计算要返回的相关值(在本例中,是要打印的字符串),该如何。那会是什么样子

建议的简单解决方案:

String bestValueFound = "None found";
if(IntStream.range(1, 100).filter(divisibleByThreeAndFiveAndFour).findFirst().isPresent()){
    bestValueFound = "Three and four and five";
} else if(IntStream.range(1, 100).filter(divisibleByThreeAndFour).findFirst().isPresent()){
    bestValueFound = "Three and four";
}else if(IntStream.range(1, 100).filter(divisibleByThreeAndFive).findFirst().isPresent()){
    bestValueFound = "Three and five";
} else if(IntStream.range(1, 100).filter(divisibleByThreeAndFive).findFirst().isPresent()){
    bestValueFound = "Five";
}
System.out.println(bestValueFound);

这似乎更糟,无论是在美学上,还是因为增加了迭代

第三部分

是否可以使用JavaSlang匹配以更漂亮、更高效的方式解决这个问题

//Note: Predicates needed to be changed from IntPredicate to Predicate<Integer> for correct compilation.
Function<Integer, String> findString = i -> API.Match(i).of(
        Case(divisibleByThreeAndFiveAndFour, "Three and four and five"),
        Case(divisibleByThreeAndFour, "Three and four"),
        Case(divisibleByThreeAndFive, "Three and five"),
        Case(divisibleByFive, "Fice"),
        Case($(), "None found"));
String bestValueFound =  IntStream.range(1, 100).boxed().map(findString).findFirst().orElseThrow(() -> new RuntimeException("Something went wrong?"));
System.out.println(bestValueFound);

这里明显的问题是“.findFirst()”,在本例中它是整数1,使整个表达式的计算结果为“None found”,然后终止

我想要的是从本质上获取与匹配中第一个谓词匹配的任何内容,并使用该值(如果存在),如果没有找到与第一个匹配的内容,则只给我与第二个匹配的内容,以此类推,如果流中没有与任何谓词匹配的值,则只给我默认值(“未找到”)

一定有更好的方法,对吧?还是我只是在浪费时间去做一些更传统、更命令式的事情

谢谢你阅读我的问题


共 (0) 个答案