Collection에서 최대 값을 얻는 방법 (예 : ArrayList)?


134

정수 값을 저장하는 ArrayList가 있습니다. 이 목록에서 최대 값을 찾아야합니다. 예를 들어 arrayList 저장 값이 다음 10, 20, 30, 40, 50과 같다고 가정하면 최대 값은 다음 과 같습니다 50.

최대 값을 찾는 효율적인 방법은 무엇입니까?

@ 편집 : 방금 확실하지 않은 솔루션을 찾았습니다.

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

Integer i = Collections.max(arrayList)

가장 높은 값을 반환합니다.

각 값을 비교하는 또 다른 방법 selection sort or binary sort algorithm  


2
값을 찾으려고 했습니까? 어디에 갇히게 되었습니까? 자신의 솔루션이 너무 비효율적입니까?
Anthony Pegram

1
그것이 많은 일을하는 경우 Java는 어셈블리로 컴파일하므로 어리석은 일을하지 않으면 간단한 반복기로 코드가 매우 효율적입니다.
Bill K

@ AnthonyPegram : 나는 어떤 정렬 알고리즘을 의미합니까, 아니면 자바에 어떤 메소드가 있습니까? BTW는 gotomanners의 답변을 확인하십시오.
user1010399


답변:


292

를 사용하여 Collections.max에 대해 충분한 Javadoc을 통해Collections API 원하는 것을 쉽게 달성하고 효율적으로 읽을 수 있습니다.

Collections.max(arrayList);

주어진 요소의 자연 순서에 따라 주어진 컬렉션의 최대 요소를 반환합니다. 컬렉션의 모든 요소는 Comparable 인터페이스를 구현해야합니다.


8
이것이 왜 대답입니까? 가장 효율적인 솔루션 은 아닙니다 . 최상의 경우, 그것의 O (N 로그 (N)) 및 그들 모두를 확인하여 최대 따기 만 O (N)이다
브랜든 긴

예, 목록을 반복하는 것이 O(n log(n))좋지만 "특히 효율적인 방법이없는 경우"는 무엇을 모두 확인하는 것 외에 더 나은 솔루션이라고 제안합니까?
gotomanners

순진한 반복은 첫 번째 요소를 정렬하고 가져 오는 것보다 최대를 사용하는 것보다 빠릅니다 (확인, 비교기가 맵에서 점수를 가져 오는 중). sort + take와 max 모두 람다를 사용했습니다.
majTheHero

31

이 질문은 거의 1 년이되었지만 객체에 대한 사용자 정의 비교기를 만들면 객체의 배열 목록에 Collections.max를 사용할 수 있음을 알았습니다.

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

캘린더 유형에 대한 맞춤 비교기가 필요하십니까?
tatmanblue

코드는 목록에서 가장 작은 값을 반환합니다. if (a.getPopulation ()> b.getPopulation ()) return -1; (a.getPopulation () <b.getPopulation ())이 -1; 첫째 // 가장 높은 값
Chandrakanth Gowda

람다도 사용할 수 있습니다. 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;
}

내 이해에서 이것은 기본적으로 Collections.max () 가하는 일이지만 목록은 일반적이므로 비교자를 사용합니다.


이것은 내 경우보다 빠릅니다.
majTheHero

14

우리는 단순히 사용 Collections.max()하고 Collections.min()방법을 사용할 수 있습니다 .

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

Integer 클래스는 Comparable을 구현하므로 Integer 목록의 최대 값 또는 최소값을 쉽게 얻을 수 있습니다.

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

클래스가 Comparable을 구현하지 않고 max 및 min 값을 찾아야하는 경우 자체 Comparator를 작성해야합니다.

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

Java 8에서는 람다를 사용하여 콜렉션이 향상되었습니다. 따라서 다음을 사용하여 max 및 min을 찾을 수 있습니다 Comparator.comparing.

암호:

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

산출:

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

5

정렬되지 않은 목록에서 최대 값을 찾는 특히 효율적인 방법은 없습니다. 모든 값을 확인하고 가장 높은 값을 반환하면됩니다.


이 정수는 어떻습니까 i = Collections.max(arrayList)? 확실하지 않은 경우 내 경우에 가장 높은 값을 반환합니다. 당신은 무엇을 말합니까?
user1010399

@ user1010399-이것은 내가 말하는 것을 정확하게 수행합니다-모든 값을 확인하고 가장 높은 값을 반환합니다.
Brendan Long

알았어 감사. 나는이 수집 방법과 정렬 알고리즘 사이에 약간 혼란 스러웠다.
user1010399

4

다음은 스트림을 사용하여 목록에서 최대 값을 찾는 세 가지 방법입니다.

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

이와 같은 모든 방법 Collections.max은 전체 컬렉션을 반복하므로 컬렉션의 크기에 비례하는 시간이 필요합니다.


3

자바 8

정수가 비슷하기 때문에 다음과 같은 하나의 라이너를 사용할 수 있습니다.

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

참고로 또 다른 점은 우리가 사용할 수 있습니다 Funtion.identity()대신 i->i으로 mapToInt예상하는 ToIntFunction완전히 다른 인터페이스와 관련이 없습니다 Function. 또한,이 인터페이스들은 단 하나의 방법을 갖는다 applyAsInt없고 identity()방법.


1

기능은 다음과 같습니다

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

gotomanners answer 외에도 다른 사람이 같은 문제 에 대한 null 안전 솔루션을 찾고 여기에 왔을 때 이것이 내가 끝낸 것입니다

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



-3

배열의 크기에 따라 멀티 스레드 솔루션도 속도를 높일 수 있습니다


이것은 실제 질문에 대한 답변보다 주석처럼 들립니다.
Pac0
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.