如何仅使用reduce来查找List中的最小值?

时间:2016-05-16 04:46:44

标签: java java-8 java-stream

我想仅使用reduce来查找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);

但在该方法的 the contract 中说:

  

identity值必须是累加器函数的标识。   这意味着对于所有t,accumulator.apply(identity, t)等于   t。累加器函数必须是关联函数。

因此,保留累加器identity的合同的唯一可能(x, y) -> x.compareTo(y) <= 0 ? x : y值是最大值。因此我们有一些鸡蛋问题。

如何解决它保留所有合同?

4 个答案:

答案 0 :(得分:5)

使用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>版本将返回一个空值;虽然需要identity并返回Integer的版本会返回标识值(类似于数学中如果添加一组数字并且它是空的,你应该得到0,如果你乘以一组数字,它是空的,你应该得到1)。因此,如果您知道您的列表是非空的,那么您实际上应该能够编写

lst.stream().reduce((x, y) -> x.compareTo(y) <= 0  ? x : y).get();

答案 1 :(得分:5)

您可以在reduce(...)上使用单个参数Stream方法来避免/推迟问题:

lst.stream().reduce((x, y) -> x.compareTo(y) <= 0  ? x : y);

这将返回Optional<Integer>,您需要处理,可能是这样的:

lst.stream().reduce((x, y) -> x.compareTo(y) <= 0  ? x : y).ifPresent(this::processValue);

但您也可以使用Math.min(...)更简洁地实现相同的结果:

lst.stream().reduce(Math::min)

还返回Optional<Integer>,但涉及装箱/取消装箱以进行比较。

您可以在运行Math.min(...)之前取消装箱,这可能会稍微提高效率:

lst.stream().mapToInt(Integer::intValue).reduce(Math::min);

这会返回一个OptionalInt,可以通过与Optional<Integer>类似的方式处理,而不会取消装箱。

答案 2 :(得分:1)

您可以使用它来获取分钟

int min = lst.stream().reduce(Integer::min).get();

获得最大值

int min = lst.stream().reduce(Integer::max).get();

答案 3 :(得分:0)

只用reduce来解决问题:

<html>
<head>
    <link rel="stylesheet" href="styles.css">
    <title title="test"></title>
    <style type="text/css">
        #bd-text {
            position: absolute;
            color: #fff;
            top: 33%;
            width: 100%;
            text-align: center;
            font-size: 20px;
            pointer-events: none;
        }
    </style>
    <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
    <script>
        $(function () {

            $("#bd-text").hide();

            $("img").mouseover(function () {
                $(this).css('border', "solid 1px #2980b9");
                $(this).css('filter', "blur(5px)");
                $("#bd-text").show();
            });

            $("img").mouseleave(function () {
                $(this).css('border', "none");
                $(this).css('filter', "blur(0px)");
                $("#bd-text").hide();
            });

        });
    </script>
</head>
<body>
    <div id="all">
        <p style="text-align:center"><img id="borderlands" src="/Images/image1.jpg"></p>
        <p style="text-align:center"><img id="unknown" src="Images/image2.jpg"></p>
        <p id="bd-text">text that fades in</p>
        <p id="dv-text">text that fades in</p>
    </div>
</body>
</html>

它并不遵守合同,因为min可能不是第一个元素,但解决了问题。