简体   繁体   English

如何从列表中收集多个最大值

[英]How do I collect multiple maximum values from a List

How to get max from an ArrayList that has more than one max? 如何从具有多个最大值的ArrayList中获取最大值? For example, if an ArrrayList contains max = 20 stored at index 2, 3 and 6, how do you get all that indicies? 例如,如果ArrrayList包含存储在索引2、3和6的max = 20,那么如何获得所有这些索引?

The obvious way is to first get maximum value by Collections.max() , then collect indicies where items are equal to max: 一种明显的方法是首先通过Collections.max()获得最大值,然后收集项等于max的索引:

public <T extends Comparable<? super T>> List<Integer> maxIndicies(List<T> input) {
    if (input.isEmpty())  // avoid exception thrown by Collections.max() if input is empty
        return Collections.emptyList();
    final T max = Collections.max(input);
    return IntStream.range(0, input.size())
               .filter(i -> input.get(i).compareTo(max) == 0)
               .boxed()
               .collect(Collectors.toList()); 
}

Additionally, I'd like to propose another solution where iteration is performed only once. 另外,我想提出另一种解决方案,其中迭代仅执行一次。 During iteration, you need to check two things for each item: 1) if it is greater than current max , set a new max and reset result list, 2) if it is equal to current max , add its index to result list: 在迭代期间,您需要检查每一项的两件事:1)如果它大于当前max ,则设置一个新的max并重置结果列表; 2)如果它等于current max ,则将其索引添加到结果列表中:

public <T extends Comparable<? super T>> List<Integer> maxIndicies(List<T> input) {
    T max = null;
    List<Integer> res = new ArrayList<>();
    for (int i = 0; i < input.size(); i++) {
       T item = input.get(i);
       if (max == null || item.compareTo(max) > 0) {   // item > max => reset
           res.clear();
           max = item;
           res.add(i);
       } else if (item.compareTo(max) == 0)            // item equals current max
           res.add(i);
    }
    return res;
}

This won't give you value of max item itself, but you can get it by any returned index, simply as: 这不会给您max项目本身的价值,但是您可以通过任何返回的索引来获取它,就像:

List<Integer> maxInd = maxIndicies(list);
maxValue = maxInd.isEmpty() ? null : list.get(maxInd.get(0));

Another approach using streams. 使用流的另一种方法。 That solution assumes that you want to know how often the max occurs (not the indices). 该解决方案假定您想知道最大值出现的频率(而不是索引)。

public static Map.Entry<Integer, Long> getMaxWithOccurrences(
        List<Integer> list) {
    return list
            .stream()
            .collect(
                    Collectors.groupingBy(i -> i, TreeMap::new,
                            Collectors.counting())).lastEntry();
}

I'd use a simple and easy to read for loop. 我会使用一个简单易懂的for循环。

public List<Integer> getMaxIndices(List<Integer> values) {
    Integer max = Collections.max(values);

    List<Integer> maxIndices = new ArrayList<>();
    for (int i = 0; i < values.size(); i++) {
        if (values.get(i).equals(max)) {
            maxIndices.add(Integer.valueOf(i));
        }
    }
    return maxIndices;
}

Integer maxValue = Collections.max(list); 整数maxValue = Collections.max(list);

int numberofMax = Collections.frequency(list, maxValue); int numberofMax = Collections.frequency(list,maxValue);

this "numberofMax" will return how many maximum values the "list" has. 此“ numberofMax”将返回“列表”具有多少个最大值。

通常的最大值查找器仅存储最大值,在这里,您将必须维护一个与最大值匹配的索引列表。

You can do it in following way: 您可以通过以下方式进行操作:

public void findMaxIndices() {
    //Your list with numbers
    List<Integer> list = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9));

    //Sorted Map which will contain key as numbers and value as list of indices where your 'key' exists in the list
    SortedMap<Integer, List<Integer>> indexMapping = new TreeMap<Integer, List<Integer>>();

    for(int i = 0; i< list.size(); i++) {
        //Get the number at index i
        int number = list.get(i);
        //Check if any index corresponding to 'number' as index has been added to your map
        List<Integer> mapping = indexMapping.get(number);
        if(mapping == null) {
            //instantiate the list if no index has been added yet 
            mapping = new ArrayList<Integer>();
            //Key as your 'number'
            indexMapping.put(number, mapping);
        }
        //Add the index of the 'number' to the mapping list, which is mapped by key as 'number'
        mapping.add(i);         
    }
    //Last key in sorted map will be your highest number in the list, get the value corresponding to it. Following prints: [8,17]
    int maxNumber = indexMapping.lastKey(); //Maximum number found
    System.out.println(indexMapping.get(maxNumber)); //Indices where maximum number exists

}

This way, you can also find indices with lowest values easily: 这样,您还可以轻松找到具有最低值的索引:

indexMapping.get(indexMapping.firstKey());

This sounds like a homework for your programming course. 这听起来像是您的编程课程的功课。 You should do it yourself but anyway here is the solution. 您应该自己做,但是无论如何这里都是解决方案。

private List<Integer> getAllMaxIndices(List<Integer> aList) {

    List<Integer> result = new ArrayList<Integer>();

    // check argument
    if (aList == null || aList.isEmpty()) {
        return result;
    }

    // initialize the list with the index of the first element
    result.add(0);

    Integer tmpInt;
    Integer tmpFirstIndexOfMaxInt;
    Integer tmpMaxInt;
    for (int i = 0; i < aList.size(); i++) {

        // save the current integer and the currently maximum integer
        tmpInt = aList.get(i);
        tmpFirstIndexOfMaxInt = result.get(0);
        tmpMaxInt = aList.get(tmpFirstIndexOfMaxInt);

        // if the current element is greater than the last found
        if (tmpInt > tmpMaxInt) {
            // empty the result
            result.clear();

            // start collecting indices again
            result.add(i);
        }
        // if the current element is equal to the last found
        else if (tmpInt.intValue() == tmpMaxInt.intValue()) {
            // insert the current index in the result
            result.add(i);
        }
    }

    return result;
}

I will leave it to you to write the code which tests this function. 我将留给您编写测试此功能的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM