java 如何简化/合并这两种方法来查找数组中的最小和最大int?[duplicate]

hivapdat  于 2022-11-27  发布在  Java
关注(0)|答案(7)|浏览(108)

此问题在此处已有答案

Is it possible to pass arithmetic operators to a method in java?(9个答案)
22天前关闭。
我写了两个方法来找出数组中最小和最大的int,但是它们几乎是一样的,所以我觉得应该有一些方法来简化这个,也许是一个方法?

private int findMin(){
    int min = arr[0];
    for(int num : arr){
        if(num<min) {
            min = num;
        }
    }
    return min;
}

private int findMax(){
    int max = arr[0];
    for(int num : arr){
        if(num>max){
            max = num;
        }
    }
    return max;
}

我不知道如何处理这类问题,所以我很想看到你的回应!
虽然this question on how to pass arithmetic operators to a methodthis question on how to get both min and max value of Java 8 stream回答了字面编程问题,但我的问题是关于如何处理方法做类似事情的问题,以及如何比较一般数组的问题。这篇文章的答案比这些问题的答案对我有更大的帮助。

41ik7eoe

41ik7eoe1#

您可以只实现一个,比如findMax,并向它传递一个Comparator,指示应该如何进行比较:

private int findMax(Comparator<Integer> comparator) {
    int max = arr[0];
    for (int num : arr) {
        if (comparator.compare(num, max) > 0) {
            max = num;
        }
    }
    return max;
}

传递Comparator.naturalOrder()以获得整数的自然排序,从而获得最大值。
传递Comparator.reverseOrder()以进行反向排序,这样您就得到了最小值。

ippsafx7

ippsafx72#

您的方法已经在IntStream中可用,它也处理空数组(不确定的极端)。

private OptionalInt findMin() {
    return IntStream.of(arr).min();
}

private OptionalInt findMax() {
    return IntStream.of(arr).max();
}

就像您选择抛出异常一样:

private int findMin() {
    return IntStream.of(arr).min().get();
}

private int findMax() {
    return IntStream.of(arr).max().get();
}

或作为方法参考:

Function<IntStream, OptionalInt> extreme = IntStream::max;

还要考虑并行功能:

IntStream.of(arr).parallel().min();

@Yay295让我们想起了IntSummaryStatistics

IntSummaryStatistics stats = new IntSummaryStatistics();
IntStream.of(arr).stream()
    .forEach(stats); // stats is an int consumer too.

或在做更多工作时

IntSummaryStatistics stats = IntStream.of(arr)
    .collect(Collectors.summarizingInt(IntSummaryStatistics::new,
                    IntSummaryStatistics::accept, 
                    IntSummaryStatistics::combine);

然后可以问几个数字:

int min = stats.getMin();
int max = stats.getMax();
int avg = stats.getAverage();
int sum = stats.getSum();

@draspa44的反馈
您可以简单地使用. summaryStatistics()结束任何IntStream、LongStream或DoubleStream。

IntSummaryStatistics stats = IntStream.of(arr)
    .summaryStatistics();
hzbexzde

hzbexzde3#

我不建议将两种责任合并为一种方法,
相反,我将通过第三个方法创建两个共享相同代码行的方法(max和min)。

public int min(int[] array){
    return most(array, (a, b) -> a < b)
}

public int max(int[] array){
    return most(array, (a, b) -> a > b)
}

private int most(int[] array, Fuction2 compare){
    int most = array[0];
    for (int num : array) {
        if (compare(num, most)) {
            most = num;
        }
    }
    return most;
}

通过这种方式,您可以轻松地更改一个方法的逻辑,而无需更改另一个方法。此外,与使用带有参数(如“max=true”)的方法相比,它更易于使用,可读性更强。

xmq68pz9

xmq68pz94#

如果int的数量很大,并且大多数情况下都需要最小值和最大值,那么只检查一次列表并同时计算最小值和最大值可能是有意义的。
当一个函数只能有一个返回值时,如何传递两个数字就成了一个问题,因此我们创建了一个特殊的结果类。

class MinMaxResult {
    public int min = 0;
    public int max = 0;
}

MinMaxResult findMinMax() {
    MinMaxResult result = new MinMaxResult();
    result.min = arr[0];
    result.max = arr[0];

    for (int num: arr) {
        if (num < result.min) {
            result.min = num;
        } else if (num > result.max) {
            result.max = num;
        }
    }

    return result;
}
z9ju0rcb

z9ju0rcb5#

您也可以调用类方法Math.minMath.max,如下所示,并以record的形式返回结果。记录是不可变的类,在Java 14中引入。

record MinMax(int min, int max) {
};

public static void main(String[] args) {
  

    int[] v = { 1, 1, 20, 3, 3, 10 };

    MinMax result = findMinMax(v);
    System.out.println(result);
    // or
    System.out.println(result.min + ", "+ result.max);
}

印刷品

MinMax[min=1, max=20]
1, 20

只需迭代数组并将方法应用于每个值和当前的最小值或最大值。

public static MinMax findMinMax(int[] values) {
    int max = values[0];
    int min = max;
    for (int i = 1; i < values.length; i++) {
        max = Math.max(max, values[i]);
        min = Math.min(min, values[i]);
    }
    return new MinMax(min, max);
}
taor4pac

taor4pac6#

你可以传入一个布尔值,如果为true,则得到最小值;如果为false,则得到最大值。诀窍是将(num < best)的结果(true或false)与布尔参数进行比较。

  • 如果isMinimum为真,那么当(num < best)为真时,我们有新的最小值。
  • 如果isMinimum为假,那么当(num < best)为假时,我们有一个新的最大值(或最大值的平局)。
private int findExtreme(bool isMinimum) {
    int best = arr[0];
    for (int num: arr) {
        if ((num < best) == isMinimum) {
            best = num;
        }
    }
    return best;
}

更好的方法是使用枚举。在函数调用中,仅仅看到一个truefalse就很难破译布尔参数。看起来像这样:

public enum Extreme {
    MINIMUM,
    MAXIMUM
}

private int find(Extreme extreme) {
    int best = arr[0];
    for (int num: arr) {
        if ((num < best) == (extreme == Extreme.MINIMUM)) {
            best = num;
        }
    }
    return best;
}
byqmnocz

byqmnocz7#

因为实际上只有一个不同,你可以传递一个布尔值来决定你想要哪个值(最小值或最大值)。

private int findExtreme(boolean findMin) {
    int solution = arr[0];
        for(int num : arr){
            if (findMin){
                if(num<min){
                    solution = num;
                }
            } else {
                if(num>max){
                    solution = num;
                }
            }
        }
    return solution;
}

相关问题