Comment obtenir la valeur maximale de la collection (par exemple ArrayList)?

134

Il existe une ArrayList qui stocke des valeurs entières. J'ai besoin de trouver la valeur maximale dans cette liste. Par exemple, supposons que les valeurs stockées de arrayList soient: 10, 20, 30, 40, 50et que la valeur maximale serait 50.

Quelle est la manière efficace de trouver la valeur maximale?

@Edit: je viens de trouver une solution pour laquelle je ne suis pas très sûr

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

Integer i = Collections.max(arrayList)

et cela renvoie la valeur la plus élevée.

Une autre façon de comparer chaque valeur, par exemple selection sort or binary sort algorithm  

user1010399
la source
2
Avez-vous essayé de trouver la valeur? Où êtes-vous resté coincé? Votre propre solution est-elle peut-être trop inefficace?
Anthony Pegram
1
Si c'est quelque chose que vous faites beaucoup, Java le compilera en assembleur, donc à moins que vous ne fassiez quelque chose de stupide, votre code sera assez efficace avec un simple itérateur.
Bill K
@AnthonyPegram: je veux dire quel algorithme de tri ou y a-t-il une méthode en java? BTW vérifiez la réponse des gotomanners.
user1010399
Pour un tableau pouvant contenir des nullvaleurs: stackoverflow.com/questions/369383/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Réponses:

292

Vous pouvez utiliser le Collections APIpour obtenir facilement ce que vous voulez - lire efficacement - assez de Javadoc pour Collections.max

Collections.max(arrayList);

Renvoie l'élément maximum de la collection donnée, selon l'ordre naturel de ses éléments. Tous les éléments de la collection doivent implémenter l'interface Comparable.

gotomanneurs
la source
8
Pourquoi est-ce la réponse acceptée? Ce n'est pas la solution la plus efficace. Dans le meilleur des cas, c'est O (n log (n)) et choisir le maximum en les vérifiant tous n'est que O (n)
Brendan Long
Oui, parcourir la liste l'est, O(n log(n))mais si "Il n'y a pas de moyen particulièrement efficace", que proposez-vous qui soit une meilleure solution en plus de les vérifier toutes?
gotomanners
L'itération naïve est plus rapide (cochée, le comparateur récupérait les scores d'une carte) que le tri et l'obtention du premier élément ou l'utilisation de max. Les deux sort + take first et max ont utilisé un lambda.
majTheHero
31

Cette question a presque un an, mais j'ai constaté que si vous créez un comparateur personnalisé pour les objets, vous pouvez utiliser Collections.max pour une liste d'objets en tableau.

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
la source
avez-vous besoin d'un comparateur personnalisé pour les types de calendrier?
tatmanblue du
Votre code renvoie la plus petite valeur de la liste, if (a.getPopulation ()> b.getPopulation ()) return -1; Ce qui précède doit changer en, if (a.getPopulation () <b.getPopulation ()) return -1; // Valeur la plus élevée d'abord
Chandrakanth Gowda
Cela peut également être fait en utilisant 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;
}

D'après ce que je comprends, c'est essentiellement ce que fait Collections.max (), bien qu'ils utilisent un comparateur car les listes sont génériques.

John
la source
C'est plus rapide que toute autre chose pour mon cas.
majTheHero
14

Nous pouvons simplement utiliser Collections.max()et Collections.min()méthode.

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
la source
8

La classe Integer implémente Comparable. Ainsi, nous pouvons facilement obtenir la valeur max ou min de la liste Integer.

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

Si une classe n'implémente pas Comparable et que nous devons trouver les valeurs max et min, nous devons écrire notre propre comparateur.

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
la source
7

Comparator.comparing

Dans Java 8, les collections ont été améliorées à l'aide de lambda. Ainsi, trouver max et min peut être accompli comme suit, en utilisant Comparator.comparing:

Code:

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

Production:

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

Il n'y a pas de moyen particulièrement efficace de trouver la valeur maximale dans une liste non triée - il vous suffit de les vérifier toutes et de renvoyer la valeur la plus élevée.

Brendan Long
la source
qu'en est-il de cet entier i = Collections.max(arrayList). il renvoie la valeur la plus élevée dans mon cas si je ne suis pas très sûr. ce que tu dis?
user1010399
@ user1010399 - Cela fait exactement ce que je dis - Il vérifie chaque valeur et renvoie la plus élevée.
Brendan Long
ok, d'accord. Merci. J'étais un peu confus entre cette méthode de collecte et l'algorithme de tri.
user1010399
4

Voici trois autres façons de trouver la valeur maximale dans une liste, à l'aide de flux:

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

Toutes ces méthodes, tout comme Collections.max, itèrent sur toute la collection, elles nécessitent donc un temps proportionnel à la taille de la collection.

Ida Bucić
la source
3

Java 8

Comme les entiers sont comparables, nous pouvons utiliser la ligne suivante dans:

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

Un autre point à noter est que nous ne pouvons pas utiliser Funtion.identity()à la place de i->icomme mapToIntprévu ToIntFunctionqui est une interface complètement différente et n'est pas liée à Function. De plus, cette interface n'a qu'une seule méthode applyAsIntet aucune identity()méthode.

akhil_mittal
la source
1

Voici la 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
la source
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
la source
1

En plus de la réponse de gotomanners , au cas où quelqu'un d'autre viendrait ici à la recherche d'une solution nulle et sûre au même problème, c'est ce avec quoi j'ai fini

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

En Java8

arrayList.stream()
         .reduce(Integer::max)
         .get()
horloge laser
la source
0
model =list.stream().max(Comparator.comparing(Model::yourSortList)).get();
Mehmet Onar
la source
-3

selon la taille de votre baie, une solution multithread peut également accélérer les choses

Niklas
la source
Cela ressemble plus à un commentaire qu'à une réponse réelle à la question.
Pac0