你对 reduction 的理解是错误的。 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
虽然这是一个概念性的观点,操作的确切顺序未指定。顺序执行将类似于
(((1 op 2) op 3) op 4)…
,而并行执行将是像上面树形图一样的执行和部分顺序执行的混合。
您可以滥用
reduce
创建结果列表,如果您首先将每个元素转换为
List
,然后使用连接每个列表的列表操作,但是,这有两个问题:
- 它不提供所需的“跳过原始列表的每个第二个元素”的逻辑;如果您查看上面的树形图,就会变得清楚,无法制定在每种可能的执行方案中都做到这一点的正确
op
函数
- 创建临时列表并将它们连接起来非常低效
后一个问题可通过使用
collect
解决,它是一种
可变缩减,因此允许您使用可变列表,您可以向其中添加项目,但它不解决第一个问题,包括所需的过滤器将违反合同,并且仅在顺序执行中有效。
因此,解决方案是为源列表范围内的所有元素定义一个
filter
,然后使用
collect
进行可变缩减以创建结果列表,大惊小怪,这正是您的原始代码所做的事情。
… .filter(integer -> integer % 2 == 0).collect(Collectors.toList())
reduce
不是正确的工具!使用filter
就像你已经建议的那样。 - isnot2badreduce
而不是collect
有什么好处吗?还是说这只是一种思维练习? - a better oliver