使用Java在原始数组中查找最大值/最小值


185

编写一个函数来确定数组中的最小/最大值很简单,例如:

/**
 * 
 * @param chars
 * @return the max value in the array of chars
 */
private static int maxValue(char[] chars) {
    int max = chars[0];
    for (int ktr = 0; ktr < chars.length; ktr++) {
        if (chars[ktr] > max) {
            max = chars[ktr];
        }
    }
    return max;
}

但这不是已经在某个地方完成了吗?


8
将原语数组转换为容器数组将有所帮助:stackoverflow.com/questions/3770289/…随后是Collections.max(Arrays.asList())
西罗Santilli郝海东冠状病六四事件法轮功

我只是喜欢Java是多么愚蠢
Farid

Answers:


173

使用Commons Lang(转换)+ Collections(最小/最大)

import java.util.Arrays;
import java.util.Collections;

import org.apache.commons.lang.ArrayUtils;

public class MinMaxValue {

    public static void main(String[] args) {
        char[] a = {'3', '5', '1', '4', '2'};

        List b = Arrays.asList(ArrayUtils.toObject(a));

        System.out.println(Collections.min(b));
        System.out.println(Collections.max(b));
   }
}

请注意,它Arrays.asList()包装了基础数组,因此它不应占用过多内存,也不应在该数组的元素上执行复制。


9
什么是ArrayUtils
Basheer AL-MOMANI

4
Arrays.asList()应该可以,但是ArrayUtils.toObject()会将的每个元素复制a到的新数组Character
EM

5
Arrays.asList(a)不起作用。您无法列出基元(List<char>在这种情况下)。首先,您需要将原始值转换为对象,这就是为什么ArrayUtils.toObject要使用它。
nessa.gp

94

你可以简单地使用新的Java 8 Stream小号,但你必须有工作int

stream实用程序类的方法Arrays为您提供了IntStream可以使用该min方法的方法。你也可以做maxsumaverage,...

getAsInt方法用于从OptionalInt

import java.util.Arrays;

public class Test {
    public static void main(String[] args){
        int[] tab = {12, 1, 21, 8};
        int min = Arrays.stream(tab).min().getAsInt();
        int max = Arrays.stream(tab).max().getAsInt();
        System.out.println("Min = " + min);
        System.out.println("Max = " + max)
    }

}

==更新==

如果执行时间很重要,并且您只想遍历数据,则可以使用如下summaryStatistics()方法

import java.util.Arrays;
import java.util.IntSummaryStatistics;

public class SOTest {
    public static void main(String[] args){
        int[] tab = {12, 1, 21, 8};
        IntSummaryStatistics stat = Arrays.stream(tab).summaryStatistics();
        int min = stat.getMin();
        int max = stat.getMax();
        System.out.println("Min = " + min);
        System.out.println("Max = " + max);
    }
}

与传统循环相比,此方法可提供更好的性能,因为该summaryStatistics方法是一种归约运算,并且允许并行化。


57

谷歌番石榴库有最大值和最小值的方法在它的字符数,类型int,long等类。

因此,您可以简单地使用:

Chars.min(myarray)

无需进行任何转换,并且可以有效地实现它。


4
它的实现方式与问题类似,不同之处在于它为长度为0的数组抛出IllegalArgumentException。(code.google.com/p/guava-libraries/source/browse/trunk/src/com/…
ColinD

3
这是这里一切的最佳解决方案。避免所有java.util.Arrays#asList varargs混淆。
香港

20

是的,这是在Collections类中完成的。请注意,您将需要手动将原始char数组转换为Character []。

简短的演示:

import java.util.*;

public class Main {

    public static Character[] convert(char[] chars) {
        Character[] copy = new Character[chars.length];
        for(int i = 0; i < copy.length; i++) {
            copy[i] = Character.valueOf(chars[i]);
        }
        return copy;
    }

    public static void main(String[] args) {
        char[] a = {'3', '5', '1', '4', '2'};
        Character[] b = convert(a);
        System.out.println(Collections.max(Arrays.asList(b)));
    }
}

1
Collections.min(myCollection); 如果要将其用于数组,则可以像Collections.min(Arrays.asList(myArray));一样进行操作。
Zed

3
将a转换char []为a Character []来确定最大值非常低效-最好为每个原始类型创建一个带有静态方法的实用工具类,类似于java.util.Arraysjava.sun.com/javase/6/docs/api/java/util/Arrays.html
Christoph

@Christoph:是的,如果数组的大小很大,我会同意。如果所讨论的应用程序进行了许多数据库调用和/或I / O操作,并且数组的大小很小(相对),则简单地指出它“低效”是没有意义的。
巴特·基尔斯

出于性能考虑,您应该使用Character.valueOf(chars[i])而不是new Character(chars[i])java.sun.com/javase/6/docs/api/java/lang/…–
Christoph

@Christoph Christoph是正确的,将数组转换为Collection进行最小最大搜索效率低下且愚蠢。
AlexWien

16
import java.util.Arrays;

public class apples {

  public static void main(String[] args) {
    int a[] = {2,5,3,7,8};
    Arrays.sort(a);

     int min =a[0];
    System.out.println(min);
    int max= a[a.length-1];
    System.out.println(max);

  }

}

4
请提供一些解释。
Mike Stockdale 2014年

3
我认为这意味着如果按照定义对数组进行排序(升序),则最小值将始终位于第一个位置a [0],最大值将始终位于最后一个位置,[a.length-1]。
杰夫

1
这是解决问题的合法且有用的方法。与其他相比,使用它的缺点是什么?
亚历克斯

8
@alex时间复杂度-排序最多是O(nlogn)事务,而Michael Rutherfurd方法是O(n)。
jajdoo 2015年

3
我们不需要排序,因为列表上的单个迭代足以找到最小值和最大值。
akhil_mittal

11

我的所有应用程序中都有一个辅助类,其方法如下:

public static double arrayMax(double[] arr) {
    double max = Double.NEGATIVE_INFINITY;

    for(double cur: arr)
        max = Math.max(max, cur);

    return max;
}

1
您应该使用double max = Double.NEGATIVE_INFINITY; 而不是double max = Double.MIN_VALUE; 由于MIN_VALUE为double是正数
krems '17

1
...或者您可以将max设置为数组中的第一项,然后从第二项进行迭代,请参见我的答案。
尼古拉斯·汉密尔顿

3

使用IntStreammax()方法,您可以轻松地做到这一点。

public static int maxValue(final int[] intArray) {
  return IntStream.range(0, intArray.length).map(i -> intArray[i]).max().getAsInt();
}

说明

  1. range(0, intArray.length)-要获取流中包含的元素数量尽可能多的流intArray

  2. map(i -> intArray[i])-将流中的每个元素映射到的实际元素intArray

  3. max()-获取此流的最大元素OptionalInt

  4. getAsInt()-打开包装OptionalInt。(您也可以在这里使用:orElse(0),以防万一OptionalInt是空的。)



2
import java.util.Random;

public class Main {

public static void main(String[] args) {
   int a[] = new int [100];
   Random rnd = new Random ();

    for (int i = 0; i< a.length; i++) {
        a[i] = rnd.nextInt(99-0)+0;
        System.out.println(a[i]);
    }

    int max = 0;          

    for (int i = 0; i < a.length; i++) {
        a[i] = max;


        for (int j = i+1; j<a.length; j++) {
            if (a[j] > max) {
               max = a[j];
            }

        }
    }

    System.out.println("Max element: " + max);
}
}

2
    public int getMin(int[] values){
        int ret = values[0];
        for(int i = 1; i < values.length; i++)
            ret = Math.min(ret,values[i]);
        return ret;
    }

这是数字,int但问题是要求原始值int, long, char, byte....
IgniteCoders

2

解决方案reduce()

int[] array = {23, 3, 56, 97, 42};
// directly print out
Arrays.stream(array).reduce((x, y) -> x > y ? x : y).ifPresent(System.out::println);

// get the result as an int
int res = Arrays.stream(array).reduce((x, y) -> x > y ? x : y).getAsInt();
System.out.println(res);
>>
97
97

在上面的代码,reduce()返回的数据Optional格式,它可以转换为int通过getAsInt()

如果要比较最大值和某个数字,可以在中设置一个起始值reduce()

int[] array = {23, 3, 56, 97, 42};
// e.g., compare with 100
int max = Arrays.stream(array).reduce(100, (x, y) -> x > y ? x : y);
System.out.println(max);
>>
100

在上面的代码中,当reduce()以身份(起始值)作为第一个参数时,它将以与身份相同的格式返回数据。借助此属性,我们可以将此解决方案应用于其他数组:

double[] array = {23.1, 3, 56.6, 97, 42};
double max = Arrays.stream(array).reduce(array[0], (x, y) -> x > y ? x : y);
System.out.println(max);
>>
97.0

1

浮动示例:

public static float getMaxFloat(float[] data) {

    float[] copy = Arrays.copyOf(data, data.length);
    Arrays.sort(copy);
    return copy[data.length - 1];
}

public static float getMinFloat(float[] data) {

    float[] copy = Arrays.copyOf(data, data.length);
    Arrays.sort(copy);
    return copy[0];
}

虽然您的解决方案可以使用,但会增加时间复杂度至O(nlogn),而使用其他答案可以在O(n)中轻松找到min。
Pramod

在这种情况下使用某种排序方式简直太疯狂了。
尼古拉斯·汉密尔顿

当需要先进行n> 1个最小/最大值,并进行一些维修时,此功能很有用。
biziclop

1

以下是在大约99%的运行次数中获得最大值的解决方案(更改0.01以获得更好的结果):

public static double getMax(double[] vals){
    final double[] max = {Double.NEGATIVE_INFINITY};

    IntStream.of(new Random().ints((int) Math.ceil(Math.log(0.01) / Math.log(1.0 - (1.0/vals.length))),0,vals.length).toArray())
            .forEach(r -> max[0] = (max[0] < vals[r])? vals[r]: max[0]);

    return max[0];
}

(不完全严重)


;-)那是“不完全认真”。犹豫要投票…
Ole VV

0

将数组传递给对其进行排序的方法,Arrays.sort()以便仅对方法使用的数组进行排序,然后将min设置为maxarray[0]并将max设置array[array.length-1]


3
可能值得注意的是,a)会修改数组,b)对于大型数组,这是更昂贵的解决方案O(nlog n)而不是O(n)
davidsheldon '16

0

获取数组的最小值/最大值的基本方法。如果需要未排序的数组,则可以创建一个副本或将其传递给返回最小值或最大值的方法。如果没有,排序数组会更好,因为在某些情况下它的执行速度更快。

public class MinMaxValueOfArray {
    public static void main(String[] args) {
        int[] A = {2, 4, 3, 5, 5};
        Arrays.sort(A);
        int min = A[0];
        int max = A[A.length -1];
        System.out.println("Min Value = " + min);        
        System.out.println("Max Value = " + max);
    }
}

2
排序的问题在于,它对O(n)问题的开销为O(n log n)。但这比已经给出的其他三个“排序数组”答案更好。
Teepeemm,2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.