Как получить максимальное значение из коллекции (например, ArrayList)?

134

Существует ArrayList, который хранит целочисленные значения. Мне нужно найти максимальное значение в этом списке. Например, предположим, что сохраненные значения arrayList: 10, 20, 30, 40, 50и максимальное значение будет 50.

Какой эффективный способ найти максимальное значение?

@ Редактировать: я только что нашел одно решение, в котором я не очень уверен

ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(100); /* add(200), add(250) add(350) add(150) add(450)*/

Integer i = Collections.max(arrayList)

и это возвращает самое высокое значение.

Другой способ сравнить каждое значение, например selection sort or binary sort algorithm  

user1010399
источник
2
Вы пытались найти значение? Где вы застряли? Возможно, ваше собственное решение слишком неэффективно?
Энтони Пеграм
1
Если вы что-то делаете много, Java будет компилировать его в ассемблер, поэтому, если вы не сделаете что-то глупое, ваш код будет достаточно эффективным с простым итератором.
Билл К
@AnthonyPegram: я имею в виду, какой алгоритм сортировки или какой-либо метод в Java? Кстати, проверьте ответ gotomanners.
user1010399
Для массива, который может содержать nullзначения: stackoverflow.com/questions/369383/…
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功

Ответы:

292

Вы можете использовать Collections APIдля достижения того, что вы хотите легко - читать эффективно - достаточно Javadoc для Collections.max

Collections.max(arrayList);

Возвращает максимальный элемент данной коллекции в соответствии с естественным порядком ее элементов. Все элементы в коллекции должны реализовывать интерфейс Comparable.

gotomanners
источник
8
Почему это принятый ответ? Это не самое эффективное решение. В лучшем случае, это O (n log (n)) и выбор максимума, проверив их все только O (n)
Брендан Лонг,
Да, итерации по списку есть, O(n log(n))но если «Не существует особенно эффективного способа», что вы предлагаете, что является лучшим решением, кроме проверки их всех?
gotomanners
Наивная итерация выполняется быстрее (проверено, компаратор извлекал баллы с карты), чем сортировка и получение первого элемента или использование max. Оба вида sort + take first и max использовали лямбду.
majTheHero
31

Этому вопросу уже почти год, но я обнаружил, что если вы создаете собственный компаратор для объектов, вы можете использовать Collections.max для списка массивов объектов.

import java.util.Comparator;

public class compPopulation implements Comparator<Country> {
    public int compare(Country a, Country b) {
        if (a.getPopulation() > b.getPopulation())
            return -1; // highest value first
        if (a.getPopulation() == b.Population())
            return 0;
        return 1;
    }
}
ArrayList<Country> X = new ArrayList<Country>();
// create some country objects and put in the list
Country ZZ = Collections.max(X, new compPopulation());
Роберт Куинн
источник
вам нужен собственный компаратор для типов календаря?
tatmanblue
Ваш код вернет наименьшее значение в списке, если (a.getPopulation ()> b.getPopulation ()) return -1; Вышеуказанное должно измениться на if (a.getPopulation () <b.getPopulation ()) return -1; // сначала наибольшее значение
Chandrakanth Gowda
Это также можно сделать с помощью лямбды: maxElement = Collections.max (collection, (el1, el2) -> el1 - el2);
majTheHero
22
public int getMax(ArrayList list){
    int max = Integer.MIN_VALUE;
    for(int i=0; i<list.size(); i++){
        if(list.get(i) > max){
            max = list.get(i);
        }
    }
    return max;
}

Насколько я понимаю, это в основном то, что делает Collections.max (), хотя они используют компаратор, поскольку списки являются общими.

Джон
источник
В моем случае это быстрее, чем что-либо еще.
majTheHero
14

Мы можем просто использовать Collections.max()и Collections.min()метод.

public class MaxList {
    public static void main(String[] args) {
        List l = new ArrayList();
        l.add(1);
        l.add(2);
        l.add(3);
        l.add(4);
        l.add(5);
        System.out.println(Collections.max(l)); // 5
        System.out.println(Collections.min(l)); // 1
    }
}
Бхавин Шах
источник
8

Класс Integer реализует Comparable, поэтому мы можем легко получить максимальное или минимальное значение списка Integer.

public int maxOfNumList() {
    List<Integer> numList = new ArrayList<>();
    numList.add(1);
    numList.add(10);
    return Collections.max(numList);
}

Если класс не реализует Comparable, и нам нужно найти максимальное и минимальное значение, мы должны написать свой собственный Comparator.

List<MyObject> objList = new ArrayList<MyObject>();
objList.add(object1);
objList.add(object2);
objList.add(object3);
MyObject maxObject = Collections.max(objList, new Comparator<MyObject>() {
    @Override
    public int compare(MyObject o1, MyObject o2) {
        if (o1.getValue() == o2.getValue()) {
            return 0;
        } else if (o1.getValue() > o2.getValue()) {
            return -1;
        } else if (o1.getValue() < o2.getValue()) {
            return 1;
        }
        return 0;
    }
});
Авиджит Кармакар
источник
7

Comparator.comparing

В Java 8 коллекции были улучшены за счет использования лямбда. Таким образом, найти max и min можно следующим образом, используя Comparator.comparing:

Код:

List<Integer> ints = Stream.of(12, 72, 54, 83, 51).collect(Collectors.toList());
System.out.println("the list: ");
ints.forEach((i) -> {
    System.out.print(i + " ");
});
System.out.println("");
Integer minNumber = ints.stream()
        .min(Comparator.comparing(i -> i)).get();
Integer maxNumber = ints.stream()
        .max(Comparator.comparing(i -> i)).get();

System.out.println("Min number is " + minNumber);
System.out.println("Max number is " + maxNumber);

Вывод:

 the list: 12 72 54 83 51  
 Min number is 12 
 Max number is 83
Кик Бутовский
источник
5

Нет особенно эффективного способа найти максимальное значение в несортированном списке - вам просто нужно проверить их все и вернуть максимальное значение.

Брендан Лонг
источник
как насчет этого Integer i = Collections.max(arrayList). он возвращает наивысшее значение в моем случае, не очень ли я уверен. что вы говорите?
user1010399
@ user1010399 - Делает именно то, что я говорю - проверяет каждое значение и возвращает самое высокое.
Брендан Лонг
хорошо, хорошо. Спасибо. я был немного запутан между этим методом сбора и алгоритмом сортировки.
user1010399
4

Вот еще три способа найти максимальное значение в списке с помощью потоков:

List<Integer> nums = Arrays.asList(-1, 2, 1, 7, 3);
Optional<Integer> max1 = nums.stream().reduce(Integer::max);
Optional<Integer> max2 = nums.stream().max(Comparator.naturalOrder());
OptionalInt max3 = nums.stream().mapToInt(p->p).max();
System.out.println("max1: " + max1.get() + ", max2: " 
   + max2.get() + ", max3: " + max3.getAsInt());

Все эти методы, как и все Collections.max, перебирают всю коллекцию, поэтому для них требуется время, пропорциональное размеру коллекции.

Ида Бучич
источник
3

Java 8

Поскольку целые числа сопоставимы, мы можем использовать следующий лайнер:

List<Integer> ints = Stream.of(22,44,11,66,33,55).collect(Collectors.toList());
Integer max = ints.stream().mapToInt(i->i).max().orElseThrow(NoSuchElementException::new); //66
Integer min = ints.stream().mapToInt(i->i).min().orElseThrow(NoSuchElementException::new); //11

Еще один момент, следует отметить, что мы не можем использовать Funtion.identity()вместо , i->iкак mapToIntпредпологает , ToIntFunctionкоторый является совершенно другим интерфейсом и не связанный с Function. Более того, в этом интерфейсе есть только один метод, applyAsIntа не identity()метод.

akhil_mittal
источник
1

Вот функция

public int getIndexOfMax(ArrayList<Integer> arr){
    int MaxVal = arr.get(0); // take first as MaxVal
    int indexOfMax = -1; //returns -1 if all elements are equal
    for (int i = 0; i < arr.size(); i++) {
        //if current is less then MaxVal
        if(arr.get(i) < MaxVal ){
            MaxVal = arr.get(i); // put it in MaxVal
            indexOfMax = i; // put index of current Max
        }
    }
    return indexOfMax;  
}
СЭМ
источник
1
package in.co.largestinarraylist;

import java.util.ArrayList;
import java.util.Scanner;

public class LargestInArrayList {

    public static void main(String[] args) {

        int n;
        ArrayList<Integer> L = new ArrayList<Integer>();
        int max;
        Scanner in = new Scanner(System.in);
        System.out.println("Enter Size of Array List");
        n = in.nextInt();
        System.out.println("Enter elements in Array List");

        for (int i = 0; i < n; i++) {
            L.add(in.nextInt());
        }

        max = L.get(0);

        for (int i = 0; i < L.size(); i++) {
            if (L.get(i) > max) {
                max = L.get(i);
            }
        }

        System.out.println("Max Element: " + max);
        in.close();
    }
}
Тарун Джадхав
источник
1

В дополнение к ответу gotomanners , если кто-то еще пришел сюда в поисках нулевого безопасного решения той же проблемы, это то, что я получил

Collections.max(arrayList, Comparator.nullsFirst(Comparator.naturalOrder()))
Крис Донс Йохансен
источник
0

В Java8

arrayList.stream()
         .reduce(Integer::max)
         .get()
lasclocker
источник
0
model =list.stream().max(Comparator.comparing(Model::yourSortList)).get();
Мехмет Онар
источник
-3

в зависимости от размера вашего массива многопоточное решение также может ускорить работу

Никлас
источник
Это больше похоже на комментарий, чем на ответ на вопрос.
Pac0