Bagaimana cara mendapatkan nilai maksimum dari Koleksi (misalnya ArrayList)?


134

Ada ArrayList yang menyimpan nilai integer. Saya perlu menemukan nilai maksimum dalam daftar ini. Misalkan nilai arrayList yang tersimpan adalah: 10, 20, 30, 40, 50dan nilai maksimumnya adalah 50.

Apa cara efisien untuk menemukan nilai maksimum?

@ Edit: Saya baru saja menemukan satu solusi yang saya tidak yakin

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

Integer i = Collections.max(arrayList)

dan ini mengembalikan nilai tertinggi.

Cara lain untuk membandingkan masing-masing nilai misalnya selection sort or binary sort algorithm  


2
Sudahkah Anda berusaha menemukan nilainya? Di mana Anda terjebak? Apakah solusi Anda sendiri mungkin terlalu tidak efisien?
Anthony Pegram

1
Jika itu adalah sesuatu yang Anda lakukan banyak Java akan mengkompilasinya ke perakitan jadi kecuali Anda melakukan sesuatu yang konyol kode Anda akan sangat efisien hanya dengan iterator sederhana.
Bill K

@AnthonyPegram: maksud saya algoritma semacam apa atau apakah ada metode di java? BTW periksa jawaban Gotmanners.
user1010399


Jawaban:


292

Anda dapat menggunakan Collections APIuntuk mencapai apa yang Anda inginkan dengan mudah - baca secara efisien - cukup Javadoc untuk Collections.max

Collections.max(arrayList);

Mengembalikan elemen maksimum dari koleksi yang diberikan, sesuai dengan urutan alami dari elemen-elemennya. Semua elemen dalam koleksi harus mengimplementasikan antarmuka Sebanding.


8
Mengapa ini jawaban yang diterima? Itu bukan solusi yang paling efisien. Kasus terbaik, ini O (n log (n)) dan memilih maks dengan memeriksa semuanya hanya O (n)
Brendan Long

Ya, mengulangi daftar adalah O(n log(n))tetapi jika "Tidak ada cara yang sangat efisien", apa yang Anda usulkan yang merupakan solusi yang lebih baik selain memeriksa semuanya?
Gotomanners

Pengulangan secara naif lebih cepat (dicentang, pembanding mengambil skor dari Peta) daripada mengurutkan dan mendapatkan elemen pertama atau menggunakan maks. Kedua sort + take first dan max menggunakan lambda.
majTheHero

31

Pertanyaan ini sudah hampir satu tahun tetapi saya telah menemukan bahwa jika Anda membuat komparator khusus untuk objek, Anda dapat menggunakan Collections.max untuk daftar objek array.

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

apakah Anda memerlukan pembanding khusus untuk jenis Kalender?
tatmanblue

Kode Anda mengembalikan nilai terkecil dalam daftar, jika (a.getPopulation ()> b.getPopulation ()) mengembalikan -1; Di atas harus berubah menjadi, jika (a.getPopulation () <b.getPopulation ()) mengembalikan -1; // nilai tertinggi pertama
Chandrakanth Gowda

Ini dapat dilakukan dengan menggunakan lambda juga: 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;
}

Dari pemahaman saya, ini pada dasarnya apa yang Collections.max () lakukan, meskipun mereka menggunakan komparator karena daftar generik.


Ini lebih cepat dari apa pun untuk kasus saya.
majTheHero

14

Kita cukup menggunakan Collections.max()dan Collections.min()metode.

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

Kelas integer mengimplementasikan Comparable. Jadi kita dapat dengan mudah mendapatkan nilai maks atau min dari daftar Integer.

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

Jika sebuah kelas tidak mengimplementasikan Comparable dan kita harus menemukan nilai maks dan min maka kita harus menulis Comparator kita sendiri.

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

Di Jawa 8, Koleksi telah ditingkatkan dengan menggunakan lambda. Jadi menemukan max dan min dapat dilakukan sebagai berikut, menggunakan Comparator.comparing:

Kode:

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

Keluaran:

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

5

Tidak ada cara yang sangat efisien untuk menemukan nilai maksimum dalam daftar yang tidak disortir - Anda hanya perlu memeriksa semuanya dan mengembalikan nilai tertinggi.


bagaimana dengan Integer ini i = Collections.max(arrayList). itu mengembalikan nilai tertinggi dalam kasus saya apakah saya tidak terlalu yakin. apa kamu bilang?
user1010399

@ user1010399 - Ini tidak persis apa yang saya katakan - Ini memeriksa setiap nilai dan mengembalikan yang tertinggi.
Brendan Long

OK baiklah. Terima kasih. saya agak bingung antara metode pengumpulan & algoritma penyortiran ini.
user1010399

4

Berikut adalah tiga cara lain untuk menemukan nilai maksimum dalam daftar, menggunakan aliran:

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

Semua metode ini, sama seperti Collections.max, mengulangi seluruh koleksi, karenanya mereka membutuhkan waktu yang proporsional dengan ukuran koleksi.


3

Java 8

Karena bilangan bulat sebanding, kami dapat menggunakan liner berikut dalam:

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

Hal lain yang perlu diperhatikan adalah kita tidak bisa menggunakan Funtion.identity()di tempat i->iseperti mapToIntmengharapkan ToIntFunctionyang merupakan antarmuka yang sama sekali berbeda dan tidak berhubungan dengan Function. Apalagi antarmuka ini hanya memiliki satu metode applyAsIntdan tidak ada identity()metode.


1

Inilah fucntion-nya

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

Selain jawaban gotomanners , kalau-kalau ada orang lain datang ke sini mencari solusi aman nol untuk masalah yang sama, inilah yang akhirnya saya dapatkan

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


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

-3

tergantung pada ukuran array Anda, solusi multithreaded juga dapat mempercepat beberapa hal


Ini terdengar lebih seperti komentar daripada jawaban aktual untuk pertanyaan itu.
Pac0
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.