use*_*882 3 java java-8 java-stream
我只想reduce在a中找到最小值List<Integer>.这是我最初的想法:
List<Integer> lst;
//init
//assuming it's not empty
lst.stream().reduce(lst.get(0), (x, y) -> x.compareTo(y) <= 0 ? x : y);
Run Code Online (Sandbox Code Playgroud)
该
identity值必须是累加器函数的标识.这意味着对于所有t,accumulator.apply(identity, t)等于t.累加器函数必须是关联函数.
因此,identity保留累加器合约的唯一可能值(x, y) -> x.compareTo(y) <= 0 ? x : y是最大值.因此我们有一些鸡蛋问题.
如何解决它保留所有合同?
使用Integer.MAX_VALUE.其他一切都将小于或等于,所以它满足了min(identity, t) == t所有人的合同t.
进一步研究后,我认为你不需要这个身份.有一个reduce只是将函数作为参数,http://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#reduce-java.util.function.BinaryOperator-.这将返回Optional<Integer>而不是Integer.我相信,原因是该方法必须处理流中没有元素的情况.在这种情况下,Optional<Integer>版本将返回一个空值; 虽然需要a identity并且返回an 的版本Integer会返回标识值(类似于数学中如果添加一组数字并且它是空的,你应该得到0,如果你乘以一组数字并且它是空的,你应该获得1).所以,如果你知道你的列表是非空的,你实际上应该能够写
lst.stream().reduce((x, y) -> x.compareTo(y) <= 0 ? x : y).get();
Run Code Online (Sandbox Code Playgroud)
您可以通过使用单个参数reduce(...)方法来避免/推迟问题,Stream如下所示:
lst.stream().reduce((x, y) -> x.compareTo(y) <= 0 ? x : y);
Run Code Online (Sandbox Code Playgroud)
这将返回一个Optional<Integer>你需要处理的东西,可能是这样的:
lst.stream().reduce((x, y) -> x.compareTo(y) <= 0 ? x : y).ifPresent(this::processValue);
Run Code Online (Sandbox Code Playgroud)
但您也可以使用Math.min(...)更简洁地实现相同的结果:
lst.stream().reduce(Math::min)
Run Code Online (Sandbox Code Playgroud)
还返回一个Optional<Integer>,但涉及拳击/拆箱进行比较.
您可以在运行之前取消装箱,Math.min(...)这可能会稍微提高效率:
lst.stream().mapToInt(Integer::intValue).reduce(Math::min);
Run Code Online (Sandbox Code Playgroud)
这将返回一个OptionalInt可以在Optional<Integer>没有取消装箱的情况下以类似方式处理的内容.