Нахождение максимального / минимального значения в массиве примитивов с помощью Java

Нетривиально написать функцию для определения минимального / максимального значения в массиве, например:

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

но разве это где-то еще не сделано?


person Nick Heiner    schedule 27.09.2009    source источник
comment
Массив примитива к массиву контейнеров может помочь: stackoverflow.com/questions/3770289/, за которым следует Collections.max(Arrays.asList()).   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 13.03.2015
comment
Мне просто нравится, насколько тупая Java   -  person Farid    schedule 26.06.2020


Ответы (14)


Использование Commons Lang (для преобразования) + Коллекции (в мин. / Макс.)

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() обертывает базовый массив, поэтому он не должен быть слишком интенсивным для памяти и не должен выполнять копирование элементов массива.

person Michael Rutherfurd    schedule 28.09.2009
comment
что такое ArrayUtils - person Basheer AL-MOMANI; 18.05.2016
comment
Arrays.asList() должно быть в порядке, но ArrayUtils.toObject() скопирует каждый элемент a в новый массив Character. - person E.M.; 22.10.2016
comment
Arrays.asList(a) не работает. Вы не можете составить список примитивов (в данном случае List<char>). Сначала вам нужно преобразовать примитивные значения в объекты, и поэтому используется ArrayUtils.toObject. - person nessa.gp; 16.02.2017

Вы можете просто использовать новую версию Java 8 Streams но вы должны работать с int.

stream метод служебного класса Arrays дает вам IntStream, на котором можно использовать Метод min. Вы также можете сделать _7 _, _8 _, average , ...

Используется метод 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)
    }

}

== ОБНОВЛЕНИЕ ==

Если время выполнения важно и вы хотите просмотреть данные только один раз, вы можете использовать _ 13_

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

Этот подход может обеспечить лучшую производительность, чем классический цикл, потому что _ 15_ - это операция сокращения и позволяет распараллеливать.

person Ortomala Lokni    schedule 07.06.2015

В библиотеке Google Guava есть методы min и max в своих Chars, Ints, Longs и т. Д. классы.

Таким образом, вы можете просто использовать:

Chars.min(myarray)

Никаких преобразований не требуется и, предположительно, это эффективно реализовано.

person Andrew McKinlay    schedule 01.11.2009
comment
Он реализован более или менее так же, как в вопросе, за исключением того, что выдает исключение IllegalArgumentException для массива длиной 0. (code.google.com/p/guava-libraries/source/browse/trunk/src/com/) - person ColinD; 10.12.2009
comment
Это лучшее решение из всего, что здесь есть. Избегает всей этой путаницы java.util.Arrays # asList varargs. - person Kong; 26.05.2014

Да, это делается в Коллекции класс. Обратите внимание, что вам нужно будет вручную преобразовать ваш примитивный массив 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)));
    }
}
person Bart Kiers    schedule 27.09.2009
comment
Collections.min (myCollection); Если вы хотите использовать его для массивов, вы можете сделать это как Collections.min (Arrays.asList (myArray)); - person Zed; 28.09.2009
comment
преобразование char [] в Character [] только для определения максимума довольно неэффективно - лучше создать служебный класс со статическими методами для каждого примитивного типа, подобными java.util.Arrays: java.sun.com/javase/6/docs/api/java/util/Arrays.html - person Christoph; 28.09.2009
comment
@Christoph: да, если размер массива большой, соглашусь. Просто заявить, что это неэффективно, не имеет смысла, если рассматриваемое приложение выполняет много вызовов базы данных и / или операций ввода-вывода, а размер массива (относительный) мал. - person Bart Kiers; 28.09.2009
comment
вы должны использовать Character.valueOf(chars[i]) вместо new Character(chars[i]) по соображениям производительности: java.sun.com/javase/6/docs/api/java/lang/ - person Christoph; 28.09.2009
comment
@Christoph Christoph прав, неэффективно и глупо преобразовывать массив в коллекцию для поиска min max. - person AlexWien; 04.04.2013

Путем сортировки массива вы получаете первое и последнее значения 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);
  }
    
}

Хотя операция сортировки дороже, чем простой поиск минимальных / максимальных значений с помощью простого цикла. Но когда производительность не является проблемой (например, небольшие массивы или ваша стоимость не имеет значения для вашего приложения), это довольно простое решение.

Примечание: после этого модифицируется и массив.

person Lubna_Nsour    schedule 19.04.2014
comment
Я думаю, это означает, что если вы отсортируете массив (в порядке возрастания), по определению, минимальное значение всегда будет в первой позиции, a [0], а максимальное значение всегда будет в последней позиции , [a.length-1]. - person Jeff; 28.08.2014
comment
Это законный и полезный способ решения проблемы. В чем недостаток его использования по сравнению с другими? - person Alex; 03.11.2014
comment
@alex временная сложность - сортировка в лучшем случае является делом O (nlogn), в то время как подход Майкла Резерферда - O (n). - person jajdoo; 10.01.2015
comment
Нам не нужна сортировка, так как одной итерации по списку достаточно, чтобы найти min и max. - person akhil_mittal; 23.02.2015
comment
@akhil_mittal, но для этого требуется больше кода, чем сортировка, потому что нет стандартного метода Java для выполнения этой итерации - person Adam Burley; 24.03.2021

У меня есть небольшой вспомогательный класс во всех моих приложениях с такими методами, как:

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

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

    return max;
}
person Sauer    schedule 13.10.2016
comment
Вы должны использовать double max = Double.NEGATIVE_INFINITY; вместо double max = Double.MIN_VALUE; Поскольку MIN_VALUE для double положительно - person krems; 15.06.2017
comment
... или вы можете установить max для первого элемента в массиве и выполнить итерацию со 2-го элемента, см. мой ответ. - person Nicholas Hamilton; 06.03.2018

Вы можете легко сделать это с помощью IntStream и max() метода.

Пример

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 пусто.)

person winklerrr    schedule 26.08.2015

Решение с 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
person Simon Z.    schedule 26.02.2019

Вот служебный класс, предоставляющий min/max методы для примитивных типов: 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);
person Christoph    schedule 27.09.2009

Пример с поплавком:

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];
}
person Andrew    schedule 11.06.2016
comment
Хотя ваше решение будет работать, но оно увеличит временную сложность до O (nlogn), в то время как min можно легко найти в O (n), используя другие ответы. - person Pramod; 08.09.2018
comment
просто безумно использовать сортировку в этой ситуации. - person Nicholas Hamilton; 10.03.2019
comment
Это может быть полезно, когда требуется первое n ›1 наименьшее / наибольшее значение с некоторым ремонтом. - person biziclop; 30.03.2019

Вот решение, позволяющее получить максимальное значение примерно в 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];
}

(Не совсем серьезно)

person mnzl    schedule 02.11.2018
comment
;-) Это «Не совсем серьезно», хорошо. Не решаюсь проголосовать за… - person Ole V.V.; 08.12.2018

Передайте массив методу, который сортирует его с помощью Arrays.sort(), чтобы он сортировал только массив, который использует метод, затем устанавливает min на array[0] и max на array[array.length-1].

person whoduexpect    schedule 12.11.2013
comment
Вероятно, стоит отметить, что а) это изменяет массив и б) для больших массивов это более дорогое решение O (nlog n), а не O (n) - person davidsheldon; 30.08.2016

Основной способ получить минимальное / максимальное значение массива. Если вам нужен несортированный массив, вы можете создать копию или передать ее методу, который возвращает min или max. В противном случае лучше использовать отсортированный массив, поскольку в некоторых случаях он работает быстрее.

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);
    }
}
person Kim G.    schedule 18.06.2015
comment
Проблема с сортировкой заключается в том, что у нее накладные расходы O (n log n) для проблемы O (n). Но это лучше, чем три других сортировки уже предоставленных массивов ответов. - person Teepeemm; 19.06.2015

person    schedule
comment
Это для чисел int, но вопрос касается примитивных значений int, long, char, byte.... - person IgniteCoders; 06.03.2018