代码之家  ›  专栏  ›  技术社区  ›  learner

在Java8中使用嵌套for循环

  •  0
  • learner  · 技术社区  · 6 年前

    我在下面的代码中使用了嵌套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];
    }
    

    在这里我不能用 break Java流中的语句,因此我使用 return 语句,但它仍然运行内部循环,因为它不会中断它,因此性能没有提高。

    3 回复  |  直到 6 年前
        1
  •  10
  •   Daniel Pryden    6 年前

    如果我理解你的代码,你试图找出输入列表中任意两个元素之间最大的成对差异。你可以这么做 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)操作。归根结底,尽早跳出一个循环是一个优化,但不是一个非常有效的优化——找到一个渐近代价更低的方法总是 更多 比早早地跳出一个循环更有效。

        2
  •  0
  •   Mohamed Sweelam    6 年前

    java stream为这个用例提供了一个特殊的功能,即findfirst,它将停止对集合的迭代并立即返回。检查这个 https://www.google.ae/amp/s/www.geeksforgeeks.org/stream-findfirst-java-examples/amp/

    此外,您可以使用filter应用您的测试条件,您将使用filter进行检查,并首先停止。一般来说,这是为了满足你的要求。

        3
  •  0
  •   jbx    6 年前

    如果你的意图是找到最大值,你可以这样做:

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

    它将返回一个 OptionalInt 你的单子上会空的是空的。

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

    更新 在手术室澄清之后。

    创建一个名为 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();