Home > Software design >  How to collect same maximum numbers keys as List in Java 8
How to collect same maximum numbers keys as List in Java 8

Time:11-11

I want to collect the associated keys of List of maximum numbers from Map<String,Integer> in Java 8

For example:

final Map<String, Integer> map = new HashMap<>();
map.put("first", 50);
map.put("second", 10);
map.put("third", 50);

here I want to return the List of keys associated with maximum values.

For the above example, expected output is [first,third]. Because these 2 keys having the same max value.

I tried with below approach, but able to get single max key only.

final String maxKey = map.entrySet()
    .stream()
    .max(Map.Entry.comparingByValue())
    .map(Map.Entry::getKey)
    .orElse(null);

final List<String> keysInDescending = map.entrySet()
    .stream()
    .sorted(Map.Entry.<String,Integer>comparingByValue().reversed())
    .map(Map.Entry::getKey)
    .collect(Collectors.toList());

System.out.println(maxKey); // third
System.out.println(keysInDescending); //[third, first, second]

But my expected output is [first, third]. How can we achieve it in Java 8 versions?

CodePudding user response:

Slight unclearness; take max value first.

    final Integer maxValue = map.values()
        .stream()
        .max(Function.identity())
        .map(Map.Entry::getKey)
        .orElse(Integer.MIN_VALUE);

    final List<String> keysInDescending = map.entrySet()
        .stream()
        .filter(e -> maxValue.equals(e.getValue()))
        .map(e -> e.getKey())
        .sorted(Comparator.reverseOrder())
        .collect(Collectors.toList());

CodePudding user response:

Group by the values, giving a Map<Integer, List<String>>, then take the value of the biggest key

List<String> maxKeys = map.entrySet()
        .stream()
        .collect(groupingBy(Map.Entry::getValue, mapping(Map.Entry::getKey, toList())))
        .entrySet()
        .stream()
        .max(Map.Entry.<Integer, List<String>>comparingByKey())
        .orElseThrow().getValue();

That iterates twice, but the second time the map is smallest

CodePudding user response:

Step 1 : get the maxValue

        final Integer maxValue = map.values()
                .stream()
                .max(Comparator.naturalOrder())
                .orElse(null);

Step 2 : get keys associated with this max value:

            List<String> result = map.entrySet()
            .stream()
            .filter(e -> e.getValue().equals(maxValue))
            .map(Map.Entry::getKey)
            .collect(Collectors.toList());
  • Related