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  


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


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.


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

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.


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

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

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

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.


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.


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.


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

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

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


0
model =list.stream().max(Comparator.comparing(Model::yourSortList)).get();

-3

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


Cela ressemble plus à un commentaire qu'à une réponse réelle à la question.
Pac0
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.