java - 如何使用 Lambda 表达式 .reduce() 方法减少给定列表

标签 java filter lambda java-8 reduce

List<Integer> integers = Arrays.asList(1, 2, 3, 5, 6, 8, 9, 10);
integers.stream().filter((integer) -> integer % 2 == 0).collect(Collectors.toList());

如上所示integers是一个List,我们只需要从中过滤出偶数。我可以通过使用 .filter() 方法来实现。但是,有没有可能用 .reduce() 方法实现同样的效果。希望,.reduce() 方法通过执行给定的 BynaryOperation 并返回缩减列表来过滤掉所有其他元素。

如果我对 .reduce() 方法的理解不正确,请告诉我这个方法到底做了什么。

最佳答案

你对归约的理解是错误的。 reduce 将对所有元素重复应用一个函数以获得一个结果

你好像想reduce 就喜欢做

1, 2, 3, 5, 6, 8, 9, 10
│  │  │  │  │  │  │  │
└op┘  └op┘  └op┘  └op┘
  │     │     │     │
    result list

事实上,它的确如此

1, 2, 3, 5, 6, 8, 9, 10
│  │  │  │  │  │  │  │
└op┘  └op┘  └op┘  └op┘
  │    │      │    │
  └─op─┘      └─op─┘
     │          │
     └────op────┘
           │
   final result value

尽管这是一个概念 View ,但未指定确切的操作顺序。顺序执行将像 (((1 op 2) op 3) op 4)... 而并行执行将是像上面的树一样的执行和部分顺序执行的混合。


如果您首先将每个元素转换为 List 然后使用连接每个列表的列表操作,则可以滥用 reduce 来创建结果列表,但是,有这有两个问题:

  • 它没有提供所需的“跳过每个第二个元素(原始列表的)”逻辑;如果您查看上面的树,就会清楚,不可能制定一个正确的 op 函数来在所有可能的执行场景中执行此操作
  • 创建临时列表并将它们连接起来效率很低

后一点可以通过使用collect 来解决,这是一个可变 缩减,因此,允许您使用可以添加项目的可变列表,但是,它没有解决第一点,包括所需的过滤器将违反契约(Contract)并且只能在顺序执行中工作。

因此解决方案是为源列表范围内的所有元素定义一个过滤器,然后使用collect 进行可变缩减以创建结果列表,并且,大惊喜,这正是你的原始代码所做的:

… .filter(integer -> integer % 2 == 0).collect(Collectors.toList());

关于java - 如何使用 Lambda 表达式 .reduce() 方法减少给定列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29072355/

相关文章:

java - 由于 SSL 问题,无法使用 JDBC 连接到 Azure(基于连接字符串和提供的示例)

java - 在使用Javafx播放视频时,如何让 “rect”(处理库)出现在它的前面?

java - 如何对字符串数组进行排序和过滤?

java - 在服务器根目录中运行 servlet 应用程序

search - jqGrid - 更改过滤器/搜索弹出表单 - 在页面上平坦 - 而不是对话框

java - 如何使用::运算符作为引用

java - 使用最小数量的矩形覆盖 "Manhattan skyline"

java - Android 使用 Intent 来控制媒体播放器?

kotlin - 如何在Kotlin中替换长链的forEach {}语句?

java - lambda 表达式阻止类进行 spring 组件扫描