243

It's trivial to write a function to determine the min/max value in an array, such as:

/**
 * 
 * @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;
}

but isn't this already done somewhere?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Nick Heiner
  • 119,074
  • 188
  • 476
  • 699

17 Answers17

199

Using Commons Lang (to convert) + Collections (to min/max)

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));
   }
}

Note that Arrays.asList() wraps the underlying array, so it should not be too memory intensive and it should not perform a copy on the elements of the array.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
Michael Rutherfurd
  • 13,815
  • 5
  • 29
  • 40
  • 11
    what is `ArrayUtils` – Basheer AL-MOMANI May 18 '16 at 18:39
  • 4
    `Arrays.asList()` should be fine, but `ArrayUtils.toObject()` will copy each element of `a` to a new array of `Character`. – E.M. Oct 22 '16 at 18:08
  • 8
    `Arrays.asList(a)` doesn't work. You can't make a list of primitives (`List` in this case). First you need to convert the primitive values to objects and that's why `ArrayUtils.toObject` is used. – nessa.gp Feb 16 '17 at 05:19
165

You can simply use the new Java 8 Streams but you have to work with int.

The stream method of the utility class Arrays gives you an IntStream on which you can use the min method. You can also do max, sum, average,...

The getAsInt method is used to get the value from the 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)
    }

}

==UPDATE==

If execution time is important and you want to go through the data only once you can use the summaryStatistics() method like this

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);
    }
}

This approach can give better performance than classical loop because the summaryStatistics method is a reduction operation and it allows parallelization.

Ortomala Lokni
  • 56,620
  • 24
  • 188
  • 240
61

The Google Guava library has min and max methods in its Chars, Ints, Longs, etc. classes.

So you can simply use:

Chars.min(myarray)

No conversions are required and presumably it's efficiently implemented.

Andrew McKinlay
  • 2,431
  • 1
  • 24
  • 27
  • 5
    It's implemented more or less like in the question except it throws an IllegalArgumentException for an array of length 0. (http://code.google.com/p/guava-libraries/source/browse/trunk/src/com/google/common/primitives/Chars.java) – ColinD Dec 10 '09 at 20:45
  • 3
    This is the best solution of everything here. Avoids all that java.util.Arrays#asList varargs confusion. – Kong May 25 '14 at 23:02
25

By sorting the array, you get the first and last values for min / max.

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);
  }
    
}

Although the sorting operation is more expensive than simply finding min/max values with a simple loop. But when performance is not a concern (e.g. small arrays, or your the cost is irrelevant for your application), it is a quite simple solution.

Note: the array also gets modified after this.

sɐunıɔןɐqɐp
  • 3,332
  • 15
  • 36
  • 40
Lubna_Nsour
  • 339
  • 3
  • 3
  • 3
    I think what this means to say is that if you sort the array (in ascending order), by definition, the minimum value will always be at the first position, a[0], and the maximum value will always be at the last position, [a.length-1]. – Jeff Aug 27 '14 at 21:20
  • 1
    This is a legitimate and useful way of solving the problem. What's the disadvantage of using it compared to the other ones? – Alex Nov 03 '14 at 19:34
  • 14
    @alex time complexity - sorting is at best an O(nlogn) affair, while Michael Rutherfurd approach is O(n). – jajdoo Jan 10 '15 at 13:34
  • 6
    We dont need sort as single iteration over list is enough to find min and max. – akhil_mittal Feb 23 '15 at 05:59
  • @akhil_mittal but this requires more code than a sort, because there is no Java standard method to do this iteration – Adam Burley Mar 24 '21 at 00:34
21

Yes, it's done in the Collections class. Note that you will need to convert your primitive char array to a Character[] manually.

A short demo:

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)));
    }
}
Bart Kiers
  • 166,582
  • 36
  • 299
  • 288
  • 1
    Collections.min(myCollection); If you want to use it for arrays, you can do it like Collections.min(Arrays.asList(myArray)); – Zed Sep 27 '09 at 20:33
  • 3
    converting a `char []` to a `Character []` only to determine the maximum is quite inefficient - better create a utility class with static methods for each primitive type similar to `java.util.Arrays`: http://java.sun.com/javase/6/docs/api/java/util/Arrays.html – Christoph Sep 27 '09 at 20:33
  • @Christoph: yes, if the size of the array is large, I would agree. Simply stating it is "inefficient" does not make sense if the application in question makes many database calls and/or I/O operations and the size of the array is (relative) small. – Bart Kiers Sep 27 '09 at 20:41
  • you should use `Character.valueOf(chars[i])` instead of `new Character(chars[i])` for performance reasons: http://java.sun.com/javase/6/docs/api/java/lang/Character.html#valueOf%28char%29 – Christoph Sep 27 '09 at 20:45
  • @Christoph Christoph is right, it is inefficient and stupid to transform an array to an Collection, for min max search. – AlexWien Apr 03 '13 at 22:04
11

I have a little helper class in all of my applications with methods like:

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

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

    return max;
}
Sauer
  • 1,429
  • 4
  • 17
  • 32
  • 1
    You should use double max = Double.NEGATIVE_INFINITY; instead of double max = Double.MIN_VALUE; As MIN_VALUE for double is positive – krems Jun 15 '17 at 18:56
  • 2
    ... or you could set max to the first item in the array, and iterate from the 2nd item, see my answer. – Nicholas Hamilton Mar 06 '18 at 10:47
3

Here's a utility class providing min/max methods for primitive types: Primitives.java

int [] numbers= {10,1,8,7,6,5,2};
    int a=Integer.MAX_VALUE;
    for(int c:numbers) {
        a=c<a?c:a;
        }
        
    System.out.println("Lowest value is"+a);
Christoph
  • 164,997
  • 36
  • 182
  • 240
3

You could easily do it with an IntStream and the max() method.

Example

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

Explanation

  1. range(0, intArray.length) - To get a stream with as many elements as present in the intArray.

  2. map(i -> intArray[i]) - Map every element of the stream to an actual element of the intArray.

  3. max() - Get the maximum element of this stream as OptionalInt.

  4. getAsInt() - Unwrap the OptionalInt. (You could also use here: orElse(0), just in case the OptionalInt is empty.)

winklerrr
  • 13,026
  • 8
  • 71
  • 88
3
    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;
    }
Nicholas Hamilton
  • 10,044
  • 6
  • 57
  • 88
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);
}
}
Nishu Tayal
  • 20,106
  • 8
  • 49
  • 101
hightower
  • 31
  • 4
2

A solution with 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

In the code above, reduce() returns data in Optional format, which you can convert to int by getAsInt().

If we want to compare the max value with a certain number, we can set a start value in 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

In the code above, when reduce() with an identity (start value) as the first parameter, it returns data in the same format with the identity. With this property, we can apply this solution to other arrays:

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
Simon Z.
  • 598
  • 5
  • 11
1

Example with float:

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];
}
Andrew
  • 36,676
  • 11
  • 141
  • 113
1
 IntStream.of(a).max().getAsInt()

Example:

import java.util.stream.IntStream;
public class Solution {
    public static void main(String[] args) {
        int[] a = {3, 7, 5, 2};
        int max = IntStream.of(a).max().getAsInt();
        System.out.println(max);
    }
}
Positive Navid
  • 2,481
  • 2
  • 27
  • 41
0

Pass the array to a method that sorts it with Arrays.sort() so it only sorts the array the method is using then sets min to array[0] and max to array[array.length-1].

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • 3
    It's probably worth noting that a) this modifies the array, and b) for large arrays it's a more expensive solution O(nlog n) rather than O(n) – davidsheldon Aug 30 '16 at 10:14
0

The basic way to get the min/max value of an Array. If you need the unsorted array, you may create a copy or pass it to a method that returns the min or max. If not, sorted array is better since it performs faster in some cases.

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);
    }
}
Kim G.
  • 841
  • 1
  • 8
  • 8
  • 2
    The problem with sorting is that it has an O(n log n) overhead for a O(n) problem. But this is better than the other three "sort the array" answers already given. – Teepeemm Jun 19 '15 at 12:13
0

Here is a solution to get the max value in about 99% of runs (change the 0.01 to get a better result):

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];
}

(Not completely serious)

mnzl
  • 372
  • 3
  • 14
0
    int[] arr = {1, 2, 3};

    List<Integer> list = Arrays.stream(arr).boxed().collect(Collectors.toList());
    int max_ = Collections.max(list);
    int i;
    if (max_ > 0) {
        for (i = 1; i < Collections.max(list); i++) {
            if (!list.contains(i)) {
                System.out.println(i);
                break;
            }
        }
        if(i==max_){
            System.out.println(i+1);
        }
    } else {
        System.out.println("1");
    }
}