Java: 如何使用函数式编程正确操作 BigDecimal 数组?
Java: How to properly manipulate BigDecimal array using functional programming?
那么,如何使用函数式编程获得此代码的结果:
public static final List<BigDecimal> numbers = Arrays.asList(
new BigDecimal("15"), new BigDecimal("10"), new BigDecimal("17"),
new BigDecimal("30"), new BigDecimal("18"), new BigDecimal("23"),
new BigDecimal("5"), new BigDecimal("12") );
BigDecimal totalOfReducedNumbers = BigDecimal.ZERO;
for(BigDecimal number : numbers) {
if(number.compareTo(BigDecimal.valueOf(20)) > 0)
totalOfReducedNumbers =
totalOfReducedNumbers.add(number.multiply(BigDecimal.valueOf(0.9)));
}
System.out.println("Total of reduced numbers: " + totalOfReducedNumbers);
抛出“总减少数:47.7”
如何使用 map()、reduce() 等函数式编程工具 获得相同的结果?
通过执行相同的操作,首先过滤值(您只需要大于 20 的值)。然后将这些值乘以 0.9
,最后通过执行加法来减少项。喜欢,
BigDecimal TWENTY = BigDecimal.valueOf(20);
BigDecimal POINT9 = BigDecimal.valueOf(0.9);
System.out.println("Total of reduced numbers: " + numbers.stream()
.filter(x -> x.compareTo(TWENTY) > 0)
.map(x -> x.multiply(POINT9)).reduce((a, b) -> a.add(b)).get());
输出(按要求)
Total of reduced numbers: 47.7
而且,正如评论中所建议的,我们可以通过方法参考进一步改进,使用 orElse
比原始 get()
更安全。喜欢,
System.out.println("Total of reduced numbers: " + numbers.stream()
.filter(x -> x.compareTo(TWENTY) > 0)
.map(x -> x.multiply(POINT9))
.reduce(BigDecimal::add)
.orElse(BigDecimal.ZERO));
for 循环实现是典型的 "reduce" 模式(在某些其他语言中也称为 "fold"、"Aggregate" 模式)
您正在寻找 filter
--> reduce
方法:
BigDecimal reduce =
numbers.stream()
.filter(n -> n.compareTo(BigDecimal.valueOf(20)) > 0)
.reduce(BigDecimal.ZERO,
(a, b) -> a.add(b.multiply(BigDecimal.valueOf(0.9))));
您可以进一步减少通过缓存 BigDecimal.valueOf(20)
和 BigDecimal.valueOf(0.9)
构造的对象数量,如@Elliot 的回答所示,即:
BigDecimal TWENTY = BigDecimal.valueOf(20);
BigDecimal POINT9 = BigDecimal.valueOf(0.9);
BigDecimal reduce =
numbers.stream()
.filter(n -> n.compareTo(TWENTY) > 0)
.reduce(BigDecimal.ZERO,
(a, b) -> a.add(b.multiply(POINT9)));
那么,如何使用函数式编程获得此代码的结果:
public static final List<BigDecimal> numbers = Arrays.asList(
new BigDecimal("15"), new BigDecimal("10"), new BigDecimal("17"),
new BigDecimal("30"), new BigDecimal("18"), new BigDecimal("23"),
new BigDecimal("5"), new BigDecimal("12") );
BigDecimal totalOfReducedNumbers = BigDecimal.ZERO;
for(BigDecimal number : numbers) {
if(number.compareTo(BigDecimal.valueOf(20)) > 0)
totalOfReducedNumbers =
totalOfReducedNumbers.add(number.multiply(BigDecimal.valueOf(0.9)));
}
System.out.println("Total of reduced numbers: " + totalOfReducedNumbers);
抛出“总减少数:47.7”
如何使用 map()、reduce() 等函数式编程工具 获得相同的结果?
通过执行相同的操作,首先过滤值(您只需要大于 20 的值)。然后将这些值乘以 0.9
,最后通过执行加法来减少项。喜欢,
BigDecimal TWENTY = BigDecimal.valueOf(20);
BigDecimal POINT9 = BigDecimal.valueOf(0.9);
System.out.println("Total of reduced numbers: " + numbers.stream()
.filter(x -> x.compareTo(TWENTY) > 0)
.map(x -> x.multiply(POINT9)).reduce((a, b) -> a.add(b)).get());
输出(按要求)
Total of reduced numbers: 47.7
而且,正如评论中所建议的,我们可以通过方法参考进一步改进,使用 orElse
比原始 get()
更安全。喜欢,
System.out.println("Total of reduced numbers: " + numbers.stream()
.filter(x -> x.compareTo(TWENTY) > 0)
.map(x -> x.multiply(POINT9))
.reduce(BigDecimal::add)
.orElse(BigDecimal.ZERO));
for 循环实现是典型的 "reduce" 模式(在某些其他语言中也称为 "fold"、"Aggregate" 模式)
您正在寻找 filter
--> reduce
方法:
BigDecimal reduce =
numbers.stream()
.filter(n -> n.compareTo(BigDecimal.valueOf(20)) > 0)
.reduce(BigDecimal.ZERO,
(a, b) -> a.add(b.multiply(BigDecimal.valueOf(0.9))));
您可以进一步减少通过缓存 BigDecimal.valueOf(20)
和 BigDecimal.valueOf(0.9)
构造的对象数量,如@Elliot 的回答所示,即:
BigDecimal TWENTY = BigDecimal.valueOf(20);
BigDecimal POINT9 = BigDecimal.valueOf(0.9);
BigDecimal reduce =
numbers.stream()
.filter(n -> n.compareTo(TWENTY) > 0)
.reduce(BigDecimal.ZERO,
(a, b) -> a.add(b.multiply(POINT9)));