如何从Collection中获取最大值(例如ArrayList)?


134

有一个ArrayList存储整数值。我需要在此列表中找到最大值。例如,假设arrayList的存储值为:10, 20, 30, 40, 50,最大值为50

寻找最大值的有效方法是什么?

@Edit:我只是找到一个不确定的解决方案

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会将其编译为汇编代码,因此,除非您做一些愚蠢的事情,否则仅使用一个简单的迭代器,代码就将非常高效。
比尔K

@AnthonyPegram:我的意思是java中有哪种排序算法或有什么方法?顺便说一句,检查gotomanners的答案。
user1010399


Answers:


292

您可以使用Collections API轻松实现所需的内容- 高效阅读 -足够的 Javadoc for Collections.max

Collections.max(arrayList);

根据其元素的自然顺序返回给定集合的最大元素。集合中的所有元素必须实现Comparable接口。


8
为什么这是公认的答案?这不是最有效的解决方案。最好的情况是O(n log(n)),并通过检查所有最大值来选择最大值仅为O(n)
Brendan Long

是的,在列表中进行遍历是可以的,O(n log(n))但是如果“没有特别有效的方法”,那么您认为除了检查所有内容之外,还有什么更好的解决方案?
gotomanners

天真的迭代比排序和获取第一个元素或使用max更快(检查,比较器正在从Map中获取分数)。sort + take first和max都使用了lambda。
majTheHero

31

这个问题已经有将近一年的历史了,但是我发现,如果您为对象创建自定义比较器,则可以将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

如果(a.getPopulation()> b.getPopulation())返回-1,则您的代码将返回列表中的最小值。如果(a.getPopulation()<b.getPopulation())返回-1,则以上内容必须更改;//最高

这也可以使用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;
}

据我了解,这基本上是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,并且我们必须找到最大值和最小值,那么我们就必须编写自己的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中,使用lambda增强了Collections。因此,使用以下方法可以找到最大值和最小值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)?无论我是否很确定,它都会返回最高值。你说的话?
2011年

@ user1010399-这完全符合我的意思-它检查每个值并返回最高的值。
布伦丹·朗

好的,好的。谢谢。我对这种收集方法和排序算法感到有些困惑。
2011年

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

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




-3

根据数组的大小,多线程解决方案也可能会加快速度


这听起来更像是评论,而不是问题的实际答案。
Pac0
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.