Java 8:取代传统的for循环

时间:2018-07-23 06:55:30

标签: java java-8

更改Java 8中下面给出的代码的最佳简洁方法是什么:

static int[] breakingRecords(int[] scores) {
    int lowest = 0, highest = 0, countlow = 0, counthigh = 0;
    for (int i = 0; i < scores.length; i++) {
        if (i == 0) {
            lowest = scores[0];
            highest = scores[0];
        } else {
            if (scores[i] < lowest) {
                lowest = scores[i];
                countlow++;
            } else if (scores[i] > highest) {
                highest = scores[i];
                counthigh++;
            }
        }
    }
    int rc[] = {counthigh, countlow};
    return rc;
}

注意:我知道我可以使用:

IntStream.range(0, 10).forEach(
    i -> {
      if (i == 0) {
            ...
    }

但是,为此,我需要将所有变量声明为 AtomicInteger ,这会使代码变得冗长且难以阅读。

肯定有比使用 AtomicIntegers 更好的方法。有吗?

3 个答案:

答案 0 :(得分:4)

让我们变得简单得多。您将在Stream中获得最大值和最小值。

IntStream为此提供了方法:

OptionalInt max()
OptionalInt min()

以下是使用方法的快速方法:

int[] array = {5, 6, 10, 2, 5};

OptionalInt max = Arrays.stream(array).max();
OptionalInt min = Arrays.stream(array).min();

System.out.println("min : " + min.getAsInt());
System.out.println("max : " + max.getAsInt());

请注意,您得到OptionalInt,因此应检查是否有空值,但这仅在IntStream本身为空时才会发生。因此,您甚至可以在读取数组之前进行检查。

编辑:此解决方案是在问题包括返回值之前提出的,该返回值表明重要部分是countHighcountLow部分。

答案 1 :(得分:2)

假设“最佳方式”实际上是指“表现最佳”的方式……您可能已经存在(或非常接近)!

您看到,使用 IntStream lambdas 可能有助于提高可读性,但这不会神奇地提高性能。相反的。这些结构会带来一定的开销!

换句话说:如果您的最终目标是编写以最有效的方式解决潜在问题的代码,那么“老派”是(最有可能)您的最佳选择。

流在可读性上很好地发挥了作用(明智地使用它们),它们可以帮助进行有效的过滤等,当然,当使用parallelStream()时,您可能能够更快地获得结果(通过使用更多线程)。但是,对于某些整数数组的简单直接计算,这些优点都不适用!

答案 2 :(得分:0)

您可以通过使用自定义比较器来实现这一点,该比较器接受谓词何时增加计数器以及访问方法以获取所述计数器:

public class IncrementingComparator implements Comparator<Integer>{
    private final IntPredicate doIncrement;
    private int count;

    public IncrementingComparator(IntPredicate doIncrement){
        this.doIncrement = doIncrement;
    }

    @Override
    public int compare(Integer o1, Integer o2){
        final int compareResult = o1.compareTo(o2);
        if(doIncrement.test(compareResult)){
            count++;
        }
        return compareResult;
    }

    public int count(){
        return count;
    }
}

然后您可以创建上述类的2个实例:

final IncrementingComparator maxCmp = new IncrementingComparator(i -> i > 0);
final IncrementingComparator minCmp = new IncrementingComparator(i -> i < 0);

然后可以在min()的{​​{1}}和max()操作中使用:

Stream

找到最小值和最大值后,您可以从每个比较器中提取final Optional<Integer> max = Arrays.stream(array) .boxed() .max(maxCmp); final Optional<Integer> min = Arrays.stream(array) .boxed() .min(minCmp); 值:

count
  

注意:由于比较器具有内部状态,因此只能使用一次。 (或者,可以添加final int maxCount = maxCmp.count(); final int minCount = minCmp.count(); 方法将reset()变量设置回count