java - 如何将友好号码搜索的实现从命令式转变为功能性?

标签 java functional-programming

我有一个简单的命令式实现,用于搜索友好数字的算法。现在我尝试让它更实用。

public static void search(){

    for(int i = 1; i < 10000; i++){
        for(int j = i+1; j < 10000; j++){
            if(isAmicable(i, j)){
                System.out.println(i + " " + j);
            }
        }
    }
}

public static boolean isAmicable(int i, int j){
    return sumProperDivisors(i) == j && sumProperDivisors(j) == i;
}

public static int sumProperDivisors(int num){
    int result = 0;
    for(int i = 1; i < num; i++){
        if(num%i == 0) result +=i;
    }
    return result;
}

首先,我在 search() 方法中用 IntStreams 替换了循环。

public static void streamed(){
    IntStream.range(1, 10000).forEach(p -> {    
        IntStream.range(p+1, 10000).forEach(o -> {
            if(isAmicable(p, o)) System.out.println(p + " " + o);
        });
    });
}

我没有看到任何状态或副作用会减少。 在此实现中还应该做些什么来满足 FP 范式?

最佳答案

这里有一个替代方案,可以生成所有友好对的Map,而不是产生副作用:

Map<Integer,Integer> pairs =
    IntStream.range(1, 10000)
             .boxed()
             .flatMap(p -> IntStream.range(p+1, 10000)
                                    .filter(o -> isAmicable(p, o))
                                    .mapToObj(o -> new SimpleEntry<>(p,o)))
             .collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));

当然,就性能而言,这非常糟糕,因为您对同一个 i 计算 sumProperDivisors(i) 多次。为每个 i 计算一次 sumProperDivisors(i) 一次,将结果存储在 Map 中,并检查哪些对 code>ij 满足 sumProperDivisors(i) == j && sumProperDivisors(j) == i

关于java - 如何将友好号码搜索的实现从命令式转变为功能性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56457882/

相关文章:

java - 字符串无法转换为数组

java - 什么是本体导出器?

Java Annotation : On property or on method? 有什么区别

functional-programming - Java 8 函数式编程——传递函数及其参数

java - Java EE 中的 Facade 有何意义?

java - 如何使用 ArrayList(在 Java 中)为 1x1 矩阵编写默认构造函数?

scala - Scala 中两个集合的并集

javascript - Ramda 中是否有 R.notEquals 等效项?

c# - 将多个参数传递给谓词,函数式编程

haskell - 是否可以将 F# 记录的标签用作 Haskell 中的函数或类似的函数?