【问题标题】:issue converting code from java 7 to java8将代码从 java 7 转换为 java8 的问题
【发布时间】:2021-04-09 15:29:07
【问题描述】:

我正在尝试在 Java 8 中编写以下 sn-p -

Scanner sc = new Scanner(System.in);
System.out.println("Enter the policy amount: ");
long amount = sc.nextInt();

System.out.println("Enter the interest: ");
int interest = sc.nextInt();

System.out.println("Enter the number of years: ");
int years = sc.nextInt();
sc.close();

for (int i = 1; i <= years; i++) {
    result = nextYear + amount;
    calculateInterest = result * interest / 100;
    nextYear = result + calculateInterest;
}
return nextYear;

我需要 nextYear 值,所以尝试如下使用 IntStream

IntStream intStream = IntStream.rangeClosed(1, years);

    intStream.forEach(num -> {
        result = nextYear + amount;
        calculateInterest = result * interest / 100;
        nextYear = result + calculateInterest;
    });

但是,不确定如何返回 nextYear 值。如何处理这个或者有没有其他方法可以做到这一点。请建议。谢谢。

【问题讨论】:

  • 为什么需要一个 for 循环? surley必须有一个计算利息的公式。
  • 你要计算compound interest吗?
  • 以防万一不是计息,一般怎么办?请帮忙。
  • 通常这是一个reduce操作。但也通常当你只有一个循环时你不会减少,而是当你打算将结果基于流的内容时。
  • Java 8(甚至 16)仍然允许 for 循环......它们没有任何问题。如果代码可以用streams 更好地表达(或用于娱乐/测试),我只会使用streams - 非常基于意见

标签: java lambda java-8 java-stream


【解决方案1】:

由于您的结果只是重复应用循环体,因此通过流 API 获得它的方法是通过 .iterate() 静态方法,该方法允许您生成由重复应用函数形成的类似流。

如果我们获取循环体并对其进行转换,我们会得到:

return LongStream.iterate(0, nextYear -> {
    long result = nextYear + amount;
    long calculateInterest = result * interest / 100;

    return result + calculateInterest;
})
.skip(years)
.findFirst()
.getAsLong();

使用一些算术,我们可以简化 lambda 函数的主体。通过内联resultcalculateInterest,我们只需要一行:

nextYear -> {
    return (nextYear + amount) + (nextYear + amount) * interest / 100;
}

通过消除主体并通过分组重构方程,我们得到

nextYear -> ((nextYear + amount) * (100 + interest)) / 100

因此最终的转换如下所示:

return LongStream.iterate(0, 
    nextYear -> ((nextYear + amount) * (100 + interest)) / 100
)
.skip(years)
.findFirst()
.getAsLong();

【讨论】:

    【解决方案2】:

    理论上,您可能希望使用reduce,默认值为0BinaryOperatorleft 将是定期更新的值,而 right 值仍未使用(它代表年份 - 您的 sn-ps 中的 inum)。

    double nextYear = IntStream.rangeClosed(1, years)
            .mapToDouble(i -> (double) i)
            .reduce(0.0, (left, right) -> left + amount + ((left + amount) * interest / 100));
    

    .. 或更具可读性:

    double nextYear = IntStream.rangeClosed(1, years)
            .mapToDouble(i -> (double) i)
            .reduce(0.0, (left, right) -> {
                    double result = left + amount;
                    return result + ((result) * interest / 100);
            });
    

    注意:我对你的 nextYearresultcalculateInterest 变量的类型感到很困惑。您可能想要更改 mapToDouble 或上面 sn-ps 上使用的类型。

    注意 2: 但是,如前所述,for-loop 在 Java 8 之前可用,甚至在 Java 8 之后也可用,因此没有理由停止使用它。

    注3:你确定计算正确吗?

    【讨论】:

    • 你不需要转换成double,即你可以把i -&gt; (double) i写成i -&gt; i
    • 谢谢你,这是一个很好的解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-04
    • 1970-01-01
    • 2020-10-26
    • 2011-01-04
    相关资源
    最近更新 更多