Wie erhalte ich den Maximalwert aus der Sammlung (zum Beispiel ArrayList)?


134

Es gibt eine ArrayList, in der ganzzahlige Werte gespeichert sind. Ich muss den Maximalwert in dieser Liste finden. Angenommen, die gespeicherten Werte in arrayList sind: 10, 20, 30, 40, 50und der Maximalwert wäre 50.

Was ist der effiziente Weg, um den Maximalwert zu finden?

@ Edit: Ich habe gerade eine Lösung gefunden, für die ich nicht sehr sicher bin

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

Integer i = Collections.max(arrayList)

und dies gibt den höchsten Wert zurück.

Eine andere Möglichkeit, jeden Wert zu vergleichen, z selection sort or binary sort algorithm  


2
Haben Sie versucht, den Wert zu finden? Wo bist du festgefahren? Ist Ihre eigene Lösung vielleicht zu ineffizient?
Anthony Pegram

1
Wenn Sie viel tun, kompiliert Java es zur Assembly. Wenn Sie also nichts Dummes tun, ist Ihr Code mit nur einem einfachen Iterator recht effizient.
Bill K

@AnthonyPegram: Ich meine, welcher Sortieralgorithmus oder gibt es eine Methode in Java? Überprüfen Sie übrigens die Antwort der Gotomanner.
user1010399


Antworten:


292

Sie können das verwenden Collections API, um einfach das zu erreichen, was Sie wollen - effizient lesen - genug Javadoc für Collections.max

Collections.max(arrayList);

Gibt das maximale Element der angegebenen Sammlung gemäß der natürlichen Reihenfolge ihrer Elemente zurück. Alle Elemente in der Sammlung müssen die Schnittstelle Comparable implementieren.


8
Warum ist das die akzeptierte Antwort? Es ist nicht die effizienteste Lösung. Im besten Fall ist es O (n log (n)) und die Auswahl des Maximums durch Überprüfen aller ist nur O (n)
Brendan Long

Ja, das Durchlaufen der Liste ist, O(n log(n))aber wenn "Es gibt keinen besonders effizienten Weg", was schlagen Sie vor, das eine bessere Lösung ist, als sie alle zu überprüfen?
Gotomanners

Das naive Iterieren ist schneller (aktiviert, der Komparator hat Ergebnisse von einer Karte abgerufen) als entweder das erste Element zu sortieren und abzurufen oder max. Beide sortieren + nehmen zuerst und max verwendet ein Lambda.
MajTheHero

31

Diese Frage ist fast ein Jahr alt, aber ich habe festgestellt, dass Sie Collections.max für eine Array-Liste von Objekten verwenden können, wenn Sie einen benutzerdefinierten Komparator für Objekte erstellen.

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

Benötigen Sie einen benutzerdefinierten Komparator für Kalendertypen?
Tatmanblue

Ihr Code gibt den kleinsten Wert in der Liste zurück, wenn (a.getPopulation ()> b.getPopulation ()) -1 zurückgibt; Das Obige muss sich ändern in, wenn (a.getPopulation () <b.getPopulation ()) -1 zurückgibt; // höchster Wert zuerst
Chandrakanth Gowda

Dies kann auch mit einem Lambda erfolgen: 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;
}

Nach meinem Verständnis ist dies im Grunde das, was Collections.max () tut, obwohl sie einen Komparator verwenden, da Listen generisch sind.


Dies ist schneller als alles andere für meinen Fall.
MajTheHero

14

Wir können einfach Collections.max()und Collections.min()Methode verwenden.

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

Die Integer-Klasse implementiert Comparable. So können wir leicht den Max- oder Min-Wert der Integer-Liste erhalten.

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

Wenn eine Klasse Comparable nicht implementiert und wir den Max- und Min-Wert finden müssen, müssen wir unseren eigenen Comparator schreiben.

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

In Java 8 wurden Sammlungen mithilfe von Lambda erweitert. Das Finden von Max und Min kann also wie folgt erreicht werden 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);

Ausgabe:

 the list: 12 72 54 83 51  
 Min number is 12 
 Max number is 83

5

Es gibt keine besonders effiziente Möglichkeit, den Maximalwert in einer unsortierten Liste zu finden. Sie müssen nur alle überprüfen und den höchsten Wert zurückgeben.


was ist mit diesem Integer i = Collections.max(arrayList). es gibt in meinem Fall den höchsten Wert zurück, ob ich nicht sehr sicher bin. was du sagst?
user1010399

@ user1010399 - Dies macht genau das, was ich sage - Es überprüft jeden Wert und gibt den höchsten zurück.
Brendan Long

OK, in Ordnung. Vielen Dank. Ich war etwas verwirrt zwischen dieser Sammlungsmethode und dem Sortieralgorithmus.
user1010399

4

Hier sind drei weitere Möglichkeiten, um mithilfe von Streams den Maximalwert in einer Liste zu ermitteln:

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

Alle diese Methoden Collections.maxdurchlaufen genau wie die gesamte Sammlung, daher benötigen sie Zeit, die proportional zur Größe der Sammlung ist.


3

Java 8

Da ganze Zahlen vergleichbar sind, können wir den folgenden Liner verwenden:

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

Ein weiterer Punkt ist , wir nicht verwenden können , Funtion.identity()anstatt i->iwie mapToInterwartet , ToIntFunctiondie eine ganz andere Schnittstelle ist und nicht im Zusammenhang mit Function. Darüber hinaus hat diese Schnittstelle nur eine Methode applyAsIntund keine identity()Methode.


1

Hier ist die Funktion

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

Zusätzlich zur Antwort von gotomanners für den Fall, dass jemand anderes hierher kam, um nach einer null-sicheren Lösung für dasselbe Problem zu suchen, kam ich zu diesem Ergebnis

Collections.max(arrayList, Comparator.nullsFirst(Comparator.naturalOrder()))

0

In Java8

arrayList.stream()
         .reduce(Integer::max)
         .get()

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

-3

Abhängig von der Größe Ihres Arrays kann eine Multithread-Lösung auch die Arbeit beschleunigen


Dies klingt eher nach einem Kommentar als nach einer tatsächlichen Antwort auf die Frage.
Pac0
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.