Como obter o valor máximo da coleção (por exemplo, ArrayList)?

134

Existe um ArrayList que armazena valores inteiros. Preciso encontrar o valor máximo nesta lista. Por exemplo, suponha que os valores armazenados do arrayList sejam: 10, 20, 30, 40, 50e o valor máximo seria 50.

Qual é a maneira eficiente de encontrar o valor máximo?

@ Edit: Acabei de encontrar uma solução para a qual não tenho muita certeza

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

Integer i = Collections.max(arrayList)

e isso retorna o valor mais alto.

Outra maneira de comparar cada valor, por exemplo selection sort or binary sort algorithm  

user1010399
fonte
2
Você já tentou encontrar o valor? Onde você ficou preso? A sua própria solução talvez seja ineficiente demais?
Anthony Pegram
1
Se é algo que você faz muito, Java o compila para montagem, a menos que você faça algo bobo, seu código será bastante eficiente com apenas um iterador simples.
Bill K
@ AnthonyPegram: quero dizer qual algoritmo de classificação ou existe algum método em java? Entre, verifique a resposta dos parceiros.
user1010399
Para uma disposição que pode conter nullvalores: stackoverflow.com/questions/369383/...
Ciro Santilli郝海东冠状病六四事件法轮功
Java 8: stackoverflow.com/a/52270228/1216775
akhil_mittal 8/08

Respostas:

292

Você pode usar o Collections APIpara obter o que deseja facilmente - leia com eficiência - Javadoc suficiente para Collections.max

Collections.max(arrayList);

Retorna o elemento máximo da coleção fornecida, de acordo com a ordem natural de seus elementos. Todos os elementos da coleção devem implementar a interface Comparável.

gotomanners
fonte
8
Por que essa é a resposta aceita? É não a solução mais eficiente. Melhor caso, é O (n log (n)) e escolher o máximo verificando todos eles é de apenas O (n)
Brendan Longo
Sim, a iteração na lista é, O(n log(n))mas se "Não existe uma maneira particularmente eficiente", o que você propõe que seja uma solução melhor além de verificar todas elas?
gotomanners
A iteração ingenuamente é mais rápida (marcada, o comparador estava obtendo pontuações de um mapa) do que classificando e obtendo o primeiro elemento ou usando o CPC máx. Ambos ordenam + recebem primeiro e max usa um lambda.
majTheHero 27/03/19
31

Esta pergunta tem quase um ano, mas descobri que, se você fizer um comparador personalizado para objetos, poderá usar o Collections.max para uma lista de objetos da matriz.

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());
Robert Quinn
fonte
você precisa de um comparador personalizado para tipos de calendário?
tatmanblue
Seu código retorna o menor valor da lista, se (a.getPopulation ()> b.getPopulation ()) return -1; O exemplo acima deve ser alterado para if (a.getPopulation () <b.getPopulation ()) return -1; // valor mais alto primeiro
Chandrakanth Gowda
Isso também pode ser feito usando um lambda: maxElement = Collections.max (collection, (el1, el2) -> el1 - el2);
majTheHero 27/03/19
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;
}

Pelo que entendi, é basicamente o que o Collections.max () faz, embora eles usem um comparador, pois as listas são genéricas.

John
fonte
Isso é mais rápido do que qualquer outra coisa para o meu caso.
majTheHero 27/03/19
14

Nós podemos simplesmente usar Collections.max()e Collections.min()método.

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
    }
}
Bhavin Shah
fonte
8

A classe inteira implementa Comparable. Assim, podemos obter facilmente o valor máximo ou mínimo da lista Inteiro.

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

Se uma classe não implementa Comparable e temos que encontrar os valores max e min, precisamos escrever nosso próprio 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;
    }
});
Avijit Karmakar
fonte
7

Comparator.comparing

No Java 8, as coleções foram aprimoradas usando lambda. Portanto, encontrar max e min pode ser realizado da seguinte maneira, usando Comparator.comparing:

Código:

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

Resultado:

 the list: 12 72 54 83 51  
 Min number is 12 
 Max number is 83
Kick Buttowski
fonte
5

Não existe uma maneira particularmente eficiente de encontrar o valor máximo em uma lista não classificada - basta verificar todos eles e retornar o valor mais alto.

Brendan Long
fonte
e esse inteiro i = Collections.max(arrayList)? retorna o valor mais alto no meu caso, se não tenho muita certeza. o que você diz?
user1010399
@ user1010399 - Faz exatamente o que estou dizendo - verifica todos os valores e retorna o mais alto.
Brendan Long
ok tudo bem obrigado. Fiquei um pouco confuso entre este método de coleções e algoritmo de classificação.
precisa saber é o seguinte
4

Aqui estão mais três maneiras de encontrar o valor máximo em uma lista, usando fluxos:

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

Todos esses métodos, assim como Collections.max, repetem a coleção inteira, portanto, requerem tempo proporcional ao tamanho da coleção.

Ida Bucić
fonte
3

Java 8

Como os números inteiros são comparáveis, podemos usar o seguinte liner em:

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

Outro ponto a ser observado é que não podemos usar Funtion.identity()no lugar de i->icomo mapToIntesperado, ToIntFunctionque é uma interface completamente diferente e não está relacionada a Function. Além disso, essa interface possui apenas um método applyAsInte nenhum identity()método.

akhil_mittal
fonte
1

Aqui está a fucntion

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;  
}
SAM
fonte
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();
    }
}
Tarun Jadhav
fonte
1

Além da resposta de gotomanners , caso outras pessoas venham aqui procurando uma solução nula e segura para o mesmo problema, foi com isso que acabei

Collections.max(arrayList, Comparator.nullsFirst(Comparator.naturalOrder()))
Chris Dons Johansen
fonte
0

Em Java8

arrayList.stream()
         .reduce(Integer::max)
         .get()
lasclocker
fonte
0
model =list.stream().max(Comparator.comparing(Model::yourSortList)).get();
Mehmet Onar
fonte
-3

dependendo do tamanho da sua matriz, uma solução multithread também pode acelerar as coisas

Niklas
fonte
Isso parece mais um comentário do que uma resposta real à pergunta.
Pac0