在 Java 8 中使用嵌套 for 循环

问题描述 投票:0回答:4

我在下面的代码中使用嵌套 for 循环,并且有一些条件会破坏内部 for 循环,这提高了该代码的性能。

public static int getMaxValue(List<Integer> list) {
    int result = -1;
    for(int i=0; i<list.size(); i++) {
        for(int j=i+1; j<list.size(); j++) {
            if(list.get(j) - list.get(i) <= 0) break;
            if(list.get(j) - list.get(i) > result) {
                result = list.get(j) - list.get(i);
            }
        }
    }
    return result;
}

现在我如何使用 Java 8 流来执行相同的逻辑?我想出了下面的代码:

public static int getMaxValue(List<Integer> list) {
    int[] result = { -1 };
    IntStream.range(0, list.size()).forEach(i -> {
        IntStream.range(i + 1, list.size()).forEach(j -> {
            if(list.get(j) - list.get(i) <= 0) return;

            if(list.get(j) - list.get(i) > result[0]) {
                result[0] = list.get(j) - list.get(i);
            }
        });
    });
    return result[0];
}

这里我不能在java流中使用

break
语句,所以我使用了
return
语句,但是仍然运行内部循环,因为它不会破坏它,性能没有提高。

java java-8
4个回答
10
投票

如果我理解你的代码,你正在尝试找到输入列表中任意两个元素之间的最大成对差异。您可以使用

IntSummaryStatistics
来做到这一点:

public static int getMaxValue(List<Integer> list) {
    IntSummaryStatistics stats = list.stream()
        .mapToInt(Integer::intValue)
        .summaryStatistics();
    return stats.getMax() - stats.getMin();
}

这是一个 O(n) 操作,具有 O(1) 辅助存储。仍然不需要 O(n²) 操作。最终,尽早跳出循环是一种优化,但不是一种非常有效的优化 - 找到一种渐近成本较低的方法总是比提前跳出循环更更有效。


0
投票
Java流为此用例提供了一个特殊的功能,即findFirst,它将停止对集合的迭代并立即返回。检查这个

https://www.google.ae/amp/s/www.geeksforgeeks.org/stream-findfirst-java-examples/amp/

此外,您可以使用过滤器应用测试条件,您将使用过滤器进行检查并 findFirst 停止。这通常是按照您的要求进行的。


0
投票
如果您的目的是找到最大值,您可以这样做:

list.stream() .mapToInt(Integer::intValue) .max();

它将返回一个

OptionalInt

 ,您的列表为空。

否则不确定你想用你的代码实现什么......

更新在Op澄清后

创建一个名为

MinMax

 的小类,它存储 
min
max
,例如:

public class MinMax { private final int min; private final int max; private MinMax(int min, int max) { this.min = min; this.max = max; } public int getDifference() { return this.max - this.min; } public MinMax accept(int element) { int newMin = element < min ? element : min; int newMax = element > max ? element : max; if (newMin != min || newMax != max) { return new MinMax(newMin, newMax); } else { return this; } } public static MinMax seed() { return new MinMax(Integer.MAX_VALUE, Integer.MIN_VALUE); } }

这个新类负责跟踪最小值和最大值。 现在你可以做类似的事情:

int result = list.stream() .reduce(MinMax.seed(), MinMax::accept()) .getDifference();
    

0
投票
如果我没记错的话,你是否从你的日志猫那里得到了像数字这样的嵌套循环,因为它正在从你无法控制的某种外环中获取消息或其他东西?

© www.soinside.com 2019 - 2024. All rights reserved.