[英]How to reduce given list by using Lambda expression .reduce() method
List<Integer> integers = Arrays.asList(1, 2, 3, 5, 6, 8, 9, 10);
integers.stream().filter((integer) -> integer % 2 == 0).collect(Collectors.toList());
As shown above integers
is a List, from which we need to filter only even numbers. 如上所示,
integers
是一个List,我们只需要过滤偶数。 I can achieve by using .filter()
method. 我可以通过使用
.filter()
方法来实现。 But, is there any possibility to achieve the same with .reduce()
method. 但是,有没有可能用
.reduce()
方法实现相同的功能。 Hope, .reduce()
method filtered out all the other elements by performing given BynaryOperation and return reduced list. 希望,
.reduce()
方法通过执行给定的BynaryOperation并返回简化列表来过滤掉所有其他元素。
If my understanding is not correct on .reduce()
method, please let me know what exactly this method do. 如果我对
.reduce()
方法的理解不正确,请告诉我这个方法究竟是做什么的。
Your understanding of reduction is wrong. 你对减少的理解是错误的。
reduce
will apply a function on all elements repeatedly to get one single result . reduce
将重复对所有元素应用函数以获得单个结果 。
You seem to think of reduce like doing 你似乎认为减少就像做
1, 2, 3, 5, 6, 8, 9, 10
│ │ │ │ │ │ │ │
└op┘ └op┘ └op┘ └op┘
│ │ │ │
result list
whereas, in fact, it does 事实上,确实如此
1, 2, 3, 5, 6, 8, 9, 10
│ │ │ │ │ │ │ │
└op┘ └op┘ └op┘ └op┘
│ │ │ │
└─op─┘ └─op─┘
│ │
└────op────┘
│
final result value
Though, this is a conceptional view, the exact order of operations is unspecified. 虽然这是一个概念视图,但未指定操作的确切顺序。 A sequential execution will be like
(((1 op 2) op 3) op 4)…
while a parallel execution will be a mixture of an execution like the tree above and partial sequential execution(s). 顺序执行将类似于
(((1 op 2) op 3) op 4)…
而并行执行将是执行的混合,如上面的树和部分顺序执行。
You can abuse reduce
to create a result list if you first convert each element into a List
and then use a list operation which concatenates each list, however, there are two problems with this: 如果首先将每个元素转换为
List
,然后使用连接每个列表的列表操作,则可以滥用reduce
来创建结果列表,但是,这有两个问题:
op
function which does that in every possible execution scenario op
函数。 The latter point can be solved by using collect
, which is a mutable reduction, hence, allows you to use mutable lists to which you can add items, however, it does not address the first point, including the desired filter would violate the contract and only work in a sequential execution. 后一点可以通过使用
collect
来解决,这是一个可变的减少,因此,允许您使用可添加项目的可变列表,但是,它没有解决第一点,包括所需的过滤器会违反合同和仅适用于顺序执行。
So the solution is to define a filter
for all elements in the scope of the source list, followed by a mutable reduction to create the result list using collect
, and, big surprise, that's exactly what you original code does: 所以解决方案是为源列表范围内的所有元素定义一个
filter
,然后使用collect
创建结果列表的可变缩减,并且,大惊喜,这正是您原始代码的作用:
… .filter(integer -> integer % 2 == 0).collect(Collectors.toList());
You can use the Stream.reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
method, which takes three parameters: 您可以使用
Stream.reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
方法,该方法有三个参数:
For example: 例如:
BinaryOperator<ArrayList<Integer>> combiner = (x, y) -> { x.addAll(y); return x; };
BiFunction<ArrayList<Integer>, Integer, ArrayList<Integer>> accumulator = (x, y) -> {
if (y % 2 == 0) {
x.add(y);
}
return x;
};
List<Integer> list = Stream.of(1, 2, 3, 5, 6, 8, 9, 10).reduce(new ArrayList<Integer>(),
accumulator,
combiner);
System.out.println(list);
Note that this solution may not work for parallel Streams. 请注意,此解决方案可能不适用于并行Streams。 Also, it's way too easier to stick to the
.filter()
approach, so I strongly advice you to do so. 另外,坚持使用
.filter()
方法太容易了,所以我强烈建议你这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.