Làm cách nào để có được giá trị tối đa từ Bộ sưu tập (ví dụ ArrayList)?


134

Có một ArrayList lưu trữ các giá trị nguyên. Tôi cần tìm giá trị tối đa trong danh sách này. Ví dụ: giả sử các giá trị được lưu trữ của ArrayList là: 10, 20, 30, 40, 50và giá trị tối đa sẽ là 50.

Cách hiệu quả để tìm giá trị tối đa là gì?

@ Chỉnh sửa: Tôi chỉ tìm thấy một giải pháp mà tôi không chắc lắm

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

Integer i = Collections.max(arrayList)

và điều này trả về giá trị cao nhất.

Một cách khác để so sánh từng giá trị, vd selection sort or binary sort algorithm  


2
Bạn đã cố gắng để tìm giá trị? Bạn bị kẹt ở đâu? Là giải pháp của riêng bạn có lẽ quá không hiệu quả?
Anthony Pegram

1
Nếu đó là thứ bạn làm rất nhiều thì Java sẽ biên dịch nó để lắp ráp, trừ khi bạn làm điều gì đó ngớ ngẩn, mã của bạn sẽ khá hiệu quả chỉ với một trình vòng lặp đơn giản.
Bill K

@AnthonyPegram: ý tôi là thuật toán sắp xếp nào hoặc có phương thức nào trong java không? BTW kiểm tra câu trả lời của gotomanners.
user1010399

Đối với một mảng có thể chứa nullcác giá trị: stackoverflow.com/questions/369383/,
Ciro Santilli 冠状 病 六四

Câu trả lời:


292

Bạn có thể sử dụng Collections APIđể đạt được những gì bạn muốn một cách dễ dàng - đọc hiệu quả - đủ Javadoc cho Collections.max

Collections.max(arrayList);

Trả về phần tử tối đa của bộ sưu tập đã cho, theo thứ tự tự nhiên của các phần tử của nó. Tất cả các yếu tố trong bộ sưu tập phải thực hiện giao diện so sánh.


8
Tại sao đây là câu trả lời được chấp nhận? Đây không phải là giải pháp hiệu quả nhất. Trường hợp tốt nhất, đó là O (n log (n)) và chọn max bằng cách kiểm tra tất cả chỉ là O (n)
Brendan Long

Có, lặp đi lặp lại qua danh sách O(n log(n))nhưng nếu "Không có cách nào đặc biệt hiệu quả", bạn đề xuất giải pháp nào tốt hơn ngoài việc kiểm tra tất cả?
gotomanners

Lặp đi lặp lại nhanh hơn (đã chọn, bộ so sánh đang tìm nạp điểm từ Bản đồ) so với việc sắp xếp và lấy phần tử đầu tiên hoặc sử dụng tối đa. Cả hai loại + mất đầu tiên và tối đa sử dụng một lambda.
majTheHero

31

Câu hỏi này đã gần một năm tuổi nhưng tôi đã thấy rằng nếu bạn tạo một bộ so sánh tùy chỉnh cho các đối tượng, bạn có thể sử dụng Collections.max cho một danh sách các đối tượng.

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

Bạn có cần một bộ so sánh tùy chỉnh cho các loại Lịch không?
tatmanblue

Mã của bạn trả về giá trị nhỏ nhất trong danh sách, nếu (a.getPopulation ()> b.getPopulation ()) return -1; Ở trên phải thay đổi thành, nếu (a.getPopulation () <b.getPopulation ()) return -1; // giá trị cao nhất trước tiên
Chandrakanth Gowda

Điều này cũng có thể được thực hiện bằng cách sử dụng lambda: maxEuity = Collections.max (bộ sưu tập, (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;
}

Theo hiểu biết của tôi, về cơ bản, đây là những gì Collections.max () thực hiện, mặc dù họ sử dụng một trình so sánh vì các danh sách là chung chung.


Điều này là nhanh hơn bất cứ điều gì khác cho trường hợp của tôi.
majTheHero

14

Chúng ta chỉ cần sử dụng Collections.max()Collections.min()phương pháp.

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

Lớp Integer thực hiện so sánh. Vì vậy, chúng ta có thể dễ dàng nhận được giá trị tối đa hoặc tối thiểu của danh sách Số nguyên.

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

Nếu một lớp không thực hiện So sánh và chúng ta phải tìm giá trị tối đa và tối thiểu thì chúng ta phải viết Trình so sánh của riêng mình.

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

Trong Java 8, Bộ sưu tập đã được tăng cường bằng cách sử dụng lambda. Vì vậy, việc tìm kiếm tối đa và tối thiểu có thể được thực hiện như sau, bằng cách sử dụngComparator.comparing :

Mã số:

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

Đầu ra:

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

5

Không có cách nào đặc biệt hiệu quả để tìm giá trị tối đa trong danh sách chưa sắp xếp - bạn chỉ cần kiểm tra tất cả và trả về giá trị cao nhất.


những gì về số nguyên này i = Collections.max(arrayList). nó trả về giá trị cao nhất trong trường hợp của tôi cho dù tôi không chắc lắm. bạn nói gì
user1010399

@ user1010399 - Điều này thực hiện chính xác những gì tôi đang nói - Nó kiểm tra mọi giá trị và trả về giá trị cao nhất.
Brendan Long

tốt ổn cả. cảm ơn. tôi đã hơi nhầm lẫn giữa phương pháp bộ sưu tập & thuật toán sắp xếp này.
user1010399

4

Dưới đây là ba cách khác để tìm giá trị tối đa trong danh sách, sử dụng luồng:

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

Tất cả các phương thức này, giống như Collections.max, lặp đi lặp lại trên toàn bộ bộ sưu tập, do đó chúng đòi hỏi thời gian tỷ lệ thuận với kích thước của bộ sưu tập.


3

Java 8

Vì các số nguyên có thể so sánh được, chúng ta có thể sử dụng một lớp lót sau:

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

Một điểm cần lưu ý là chúng ta không thể sử dụng Funtion.identity()ở vị trí của i->inhư mapToInthy vọng ToIntFunctionđó là một giao diện hoàn toàn khác nhau và không liên quan đến Function. Hơn nữa, giao diện này chỉ có một phương thức applyAsIntvà không có identity()phương pháp.


1

Đây là 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

Ngoài câu trả lời của gotomanners , trong trường hợp bất kỳ ai khác đến đây tìm kiếm một giải pháp an toàn null cho cùng một vấn đề, đây là những gì tôi đã kết thúc với

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


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

-3

tùy thuộc vào kích thước của mảng của bạn, một giải pháp đa luồng cũng có thể tăng tốc mọi thứ


Điều này nghe giống như một bình luận hơn là một câu trả lời thực sự cho câu hỏi.
Pac0
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.