¿Cómo obtener el máximo valor de la Colección (por ejemplo, ArrayList)?

134

Hay una ArrayList que almacena valores enteros. Necesito encontrar el valor máximo en esta lista. Por ejemplo, supongamos que los valores almacenados de arrayList son: 10, 20, 30, 40, 50y el valor máximo sería 50.

¿Cuál es la forma eficiente de encontrar el valor máximo?

@Edit: acabo de encontrar una solución para la que no estoy muy seguro

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

Integer i = Collections.max(arrayList)

y esto devuelve el valor más alto.

Otra forma de comparar cada valor, por ejemplo selection sort or binary sort algorithm  

usuario1010399
fuente
2
¿Has intentado encontrar el valor? ¿Dónde te quedaste atascado? ¿Es su propia solución quizás demasiado ineficiente?
Anthony Pegram
1
Si es algo que haces mucho, Java lo compilará para ensamblarlo, a menos que hagas algo tonto, tu código será bastante eficiente con solo un simple iterador.
Bill K
@AnthonyPegram: me refiero a qué algoritmo de clasificación o ¿hay algún método en Java? Por cierto, verifique la respuesta de los gotomanners.
user1010399
Para una matriz que puede contener nullvalores: stackoverflow.com/questions/369383/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Respuestas:

292

Puede usar el Collections APIpara lograr lo que desea fácilmente, leer de manera eficiente , suficiente Javadoc para Collections.max

Collections.max(arrayList);

Devuelve el elemento máximo de la colección dada, de acuerdo con el orden natural de sus elementos. Todos los elementos de la colección deben implementar la interfaz comparable.

Gotomanners
fuente
8
¿Por qué es esta la respuesta aceptada? Es no la solución más eficiente. El mejor de los casos, es O (n log (n)) y elegir el máximo al marcarlos todos es solo O (n)
Brendan Long
Sí, iterar a través de la lista es, O(n log(n))pero si "No hay una forma particularmente eficiente", ¿qué propone que sea una mejor solución además de verificarlas todas?
gotomanners
La iteración ingenua es más rápida (marcada, el comparador estaba obteniendo puntajes de un mapa) que ordenar y obtener el primer elemento o usar max. Ambos sort + take first y max usaron una lambda.
majTheHero
31

Esta pregunta tiene casi un año de antigüedad, pero descubrí que si hace un comparador personalizado para objetos, puede usar Collections.max para obtener una lista de objetos.

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
fuente
¿necesita un comparador personalizado para los tipos de calendario?
tatmanblue
Su código devuelve el valor más pequeño en la lista, si (a.getPopulation ()> b.getPopulation ()) return -1; Lo anterior tiene que cambiar a, if (a.getPopulation () <b.getPopulation ()) return -1; // valor más alto primero
Chandrakanth Gowda
Esto también se puede hacer usando un lambda: 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;
}

Según tengo entendido, esto es básicamente lo que hace Collections.max (), aunque usan un comparador ya que las listas son genéricas.

Juan
fuente
Esto es más rápido que cualquier otra cosa para mi caso.
majTheHero
14

Simplemente podemos usar Collections.max()y 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
fuente
8

La clase Integer implementa Comparable, por lo que podemos obtener fácilmente el valor máximo o mínimo de la lista Integer.

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

Si una clase no implementa Comparable y tenemos que encontrar el valor máximo y mínimo, entonces tenemos que escribir nuestro propio Comparador.

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
fuente
7

Comparator.comparing

En Java 8, las colecciones se han mejorado mediante el uso de lambda. Por lo tanto, encontrar max y min se puede lograr de la siguiente manera, 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);

Salida:

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

No hay una forma particularmente eficiente de encontrar el valor máximo en una lista sin clasificar: solo necesita verificarlos todos y devolver el valor más alto.

Brendan Long
fuente
¿Qué hay de este entero i = Collections.max(arrayList)? devuelve el valor más alto en mi caso si no estoy muy seguro. ¿Que dices?
user1010399
@ user1010399 - Esto hace exactamente lo que digo: comprueba cada valor y devuelve el más alto.
Brendan Long
Está bien. Gracias. Estaba un poco confundido entre este método de recopilación y el algoritmo de clasificación.
user1010399
4

Aquí hay tres formas más de encontrar el valor máximo en una lista, utilizando secuencias:

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 estos métodos, al igual que Collections.max, iteran sobre toda la colección, por lo tanto, requieren un tiempo proporcional al tamaño de la colección.

Ida Bucić
fuente
3

Java 8

Como los enteros son comparables, podemos usar el siguiente revestimiento en:

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

Otro punto a tener en cuenta es que no podemos usar Funtion.identity()en lugar de i->ilo mapToIntesperado, ToIntFunctionque es una interfaz completamente diferente y no está relacionada Function. Además, esta interfaz solo tiene un método applyAsInty ningún identity()método.

akhil_mittal
fuente
1

Aquí está la función

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
fuente
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
fuente
1

Además de la respuesta de gotomanners , en caso de que alguien más viniera aquí buscando una solución segura nula para el mismo problema, esto es lo que terminé con

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

En Java8

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

dependiendo del tamaño de su matriz, una solución multiproceso también podría acelerar las cosas

niklas
fuente
Esto suena más como un comentario que como una respuesta real a la pregunta.
Pac0