Recherche de la clé associée à la valeur maximale dans une carte Java


137

Quel est le moyen le plus simple d'obtenir une clé associée à la valeur maximale dans une carte?

Je crois que Collections.max (someMap) renverra la clé maximale, lorsque vous voulez la clé qui correspond à la valeur maximale.

Réponses:


136

Fondamentalement, vous devez parcourir l'ensemble d'entrées de la carte, en vous rappelant à la fois le "maximum actuellement connu" et la clé qui lui est associée. (Ou juste l'entrée contenant les deux, bien sûr.)

Par exemple:

Map.Entry<Foo, Bar> maxEntry = null;

for (Map.Entry<Foo, Bar> entry : map.entrySet())
{
    if (maxEntry == null || entry.getValue().compareTo(maxEntry.getValue()) > 0)
    {
        maxEntry = entry;
    }
}

40
+1: Vous pouvez avoir plus d'une clé avec la même valeur maximale. Cette boucle vous donnera la première qu'elle trouve.
Peter Lawrey

21
Changer> 0 en> = 0 vous donnera le dernier qu'il trouve
Aaron J Lang

1
L'utilisation des flux Java 8 aiderait-elle à simplifier davantage cela? ex: map.forEach ((k, v) -> ...
zkarthik

3
@zkarthik: Utiliser maxavec un comparateur personnalisé serait probablement plus simple.
Jon Skeet

112

Pour être complet, voici un façon de le faire

countMap.entrySet().stream().max((entry1, entry2) -> entry1.getValue() > entry2.getValue() ? 1 : -1).get().getKey();

ou

Collections.max(countMap.entrySet(), (entry1, entry2) -> entry1.getValue() - entry2.getValue()).getKey();

ou

Collections.max(countMap.entrySet(), Comparator.comparingInt(Map.Entry::getValue)).getKey();

3
(entry1, entry2) -> entry1.getValue() - entry2.getValue()est plus compact pour le comparateur.
JustABit

5
Que faire si je veux toutes les clés qui correspondent à la valeur maximale?
Mouna

4
Compact mais difficile à comprendre.
Lluis Martinez

1
Vous pouvez également utiliser la méthode de comparaison fournie par la classe IntegercountMap.entrySet().stream().max((entry1, entry2) -> Integer.compare(entry1.getValue(), entry2.getValue())).get().getKey();
Rui Filipe Pedro

3
Ou vous pouvez utiliser à la Map.Entry.comparingByValue()place
Alexey Grigorev

55

Ce code imprimera toutes les clés avec une valeur maximale

public class NewClass4 {
    public static void main(String[] args)
    {
        HashMap<Integer,Integer>map=new HashMap<Integer, Integer>();
        map.put(1, 50);
        map.put(2, 60);
        map.put(3, 30);
        map.put(4, 60);
        map.put(5, 60);
        int maxValueInMap=(Collections.max(map.values()));  // This will return max value in the Hashmap
        for (Entry<Integer, Integer> entry : map.entrySet()) {  // Itrate through hashmap
            if (entry.getValue()==maxValueInMap) {
                System.out.println(entry.getKey());     // Print the key with max value
            }
        }

    }
}

47

Un simple one liner utilisant Java-8

Key key = Collections.max(map.entrySet(), Map.Entry.comparingByValue()).getKey();


3
Solution la plus élégante et la plus minimaliste. Merci
Daniel Hári

@Samir, veuillez vérifier votre version de Java. Sleiman Jneid a explicitement mentionné qu'il fonctionnera avec Java 8
Vaibs

@Vaibs J'utilisais Java 8. Cela n'a plus d'importance, la réponse de Hilikus a fonctionné pour moi.
Samir le

Cela fonctionne pour moi comme ceci: String max_key = Collections.max(map.entrySet(), Map.Entry.comparingByValue()).getKey();
Timur Nurlygayanov

8

Voici comment le faire directement (sans boucle supplémentaire explicite) en définissant le approprié Comparator:

int keyOfMaxValue = Collections.max(
                        yourMap.entrySet(), 
                        new Comparator<Entry<Double,Integer>>(){
                            @Override
                            public int compare(Entry<Integer, Integer> o1, Entry<Integer, Integer> o2) {
                                return o1.getValue() > o2.getValue()? 1:-1;
                            }
                        }).getKey();

6

Une réponse qui renvoie une option car la carte peut ne pas avoir de valeur maximale si elle est vide: map.entrySet().stream().max(Map.Entry.comparingByValue()).map(Map.Entry::getKey);


4

Java 8 moyen d'obtenir toutes les clés avec une valeur maximale.

Integer max = PROVIDED_MAP.entrySet()
            .stream()
            .max((entry1, entry2) -> entry1.getValue() > entry2.getValue() ? 1 : -1)
            .get()
            .getValue();

List listOfMax = PROVIDED_MAP.entrySet()
            .stream()
            .filter(entry -> entry.getValue() == max)
            .map(Map.Entry::getKey)
            .collect(Collectors.toList());

System.out.println(listOfMax);

Vous pouvez également le paralléliser en utilisant parallelStream()au lieu destream()


4

J'ai deux méthodes, en utilisant cette méthode pour obtenir la clé avec la valeur maximale:

 public static Entry<String, Integer> getMaxEntry(Map<String, Integer> map){        
    Entry<String, Integer> maxEntry = null;
    Integer max = Collections.max(map.values());

    for(Entry<String, Integer> entry : map.entrySet()) {
        Integer value = entry.getValue();
        if(null != value && max == value) {
            maxEntry = entry;
        }
    }
    return maxEntry;
}

À titre d'exemple, obtenez l'entrée avec la valeur maximale en utilisant la méthode:

  Map.Entry<String, Integer> maxEntry =  getMaxEntry(map);

En utilisant Java 8, nous pouvons obtenir un objet contenant la valeur maximale:

Object maxEntry = Collections.max(map.entrySet(), Map.Entry.comparingByValue()).getKey();      

System.out.println("maxEntry = " + maxEntry);

La version java 8 est simple mais efficace! Nice work
Catbuilts

3

1. Utilisation de Stream

public <K, V extends Comparable<V>> V maxUsingStreamAndLambda(Map<K, V> map) {
    Optional<Entry<K, V>> maxEntry = map.entrySet()
        .stream()
        .max((Entry<K, V> e1, Entry<K, V> e2) -> e1.getValue()
            .compareTo(e2.getValue())
        );

    return maxEntry.get().getKey();
}

2. Utilisation de Collections.max () avec une expression Lambda

    public <K, V extends Comparable<V>> V maxUsingCollectionsMaxAndLambda(Map<K, V> map) {
        Entry<K, V> maxEntry = Collections.max(map.entrySet(), (Entry<K, V> e1, Entry<K, V> e2) -> e1.getValue()
            .compareTo(e2.getValue()));
        return maxEntry.getKey();
    }

3. Utilisation de Stream avec référence de méthode

    public <K, V extends Comparable<V>> V maxUsingStreamAndMethodReference(Map<K, V> map) {
        Optional<Entry<K, V>> maxEntry = map.entrySet()
            .stream()
            .max(Comparator.comparing(Map.Entry::getValue));
        return maxEntry.get()
            .getKey();
    }

4. Utilisation de Collections.max ()

    public <K, V extends Comparable<V>> V maxUsingCollectionsMax(Map<K, V> map) {
        Entry<K, V> maxEntry = Collections.max(map.entrySet(), new Comparator<Entry<K, V>>() {
            public int compare(Entry<K, V> e1, Entry<K, V> e2) {
                return e1.getValue()
                    .compareTo(e2.getValue());
            }
        });
        return maxEntry.getKey();
    }

5. Utilisation de l'itération simple

public <K, V extends Comparable<V>> V maxUsingIteration(Map<K, V> map) {
    Map.Entry<K, V> maxEntry = null;
    for (Map.Entry<K, V> entry : map.entrySet()) {
        if (maxEntry == null || entry.getValue()
            .compareTo(maxEntry.getValue()) > 0) {
            maxEntry = entry;
        }
    }
    return maxEntry.getKey();
}


2

Simple à comprendre. Dans le code ci-dessous, maxKey est la clé qui contient la valeur maximale.

int maxKey = 0;
int maxValue = 0;
for(int i : birds.keySet())
{
    if(birds.get(i) > maxValue)
    {
        maxKey = i;
        maxValue = birds.get(i);
    }
}

1

Cette solution est-elle correcte?

int[] a = { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7 };
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i : a) {
Integer count = map.get(i);
map.put(i, count != null ? count + 1 : 0);
}
Integer max = Collections.max(map.keySet());
System.out.println(max);
System.out.println(map);

1

Élément majoritaire / élément max dans la carte:

public class Main {
     public static void main(String[] args) {
     int[] a = {1,3,4,3,4,3,2,3,3,3,3,3};
     List<Integer> list = Arrays.stream(a).boxed().collect(Collectors.toList());
     Map<Integer, Long> map = list.parallelStream()
             .collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));
     System.out.println("Map => " + map);
     //{1=1, 2=1, 3=8, 4=2}
     map.entrySet()
     .stream()
     .max(Comparator.comparing(Entry::getValue))//compare the values and get the maximum value
     .map(Entry::getKey)// get the key appearing maximum number of times
     .ifPresentOrElse(System.out::println,() -> new RuntimeException("no such thing"));

     /*
      * OUTPUT : Map => {1=1, 2=1, 3=8, 4=2} 
      * 3
      */
     // or in  this way 
     System.out.println(".............");
     Integer maxAppearedElement = map.entrySet()
             .parallelStream()
             .max(Comparator.comparing(Entry::getValue))
             .map(Entry::getKey)
             .get();
     System.out.println(maxAppearedElement);

     } 
}

1

carte donnée

HashMap abc = nouveau HashMap <> ();

obtenir toutes les entrées de carte avec un maximum de valeurs.

vous pouvez utiliser l'une des méthodes ci-dessous dans le filtre pour obtenir des entrées de carte respectives pour des ensembles de valeurs minimales ou maximales

Collections.max(abc.values())
Collections.min(abc.values())
Collections.max(abc.keys())
Collections.max(abc.keys())

abc.entrySet().stream().filter(entry -> entry.getValue() == Collections.max(abc.values()))

si seulement vous voulez obtenir les clés de la carte de filtre

abc.entrySet()
       .stream()
       .filter(entry -> entry.getValue() == Collections.max(abc.values()))
       .map(Map.Entry::getKey);

si vous souhaitez obtenir les valeurs de la carte filtrée

abc.entrySet()
      .stream()
      .filter(entry -> entry.getValue() == Collections.max(abc.values()))
      .map(Map.Entry::getvalue)

si vous voulez obtenir toutes ces clés dans une liste:

abc.entrySet()
  .stream()
  .filter(entry -> entry.getValue() == Collections.max(abc.values()))
  .map(Map.Entry::getKey)
  .collect(Collectors.toList())

si vous souhaitez obtenir toutes ces valeurs dans une liste:

abc.entrySet()
  .stream()
  .filter(entry -> entry.getValue() == Collections.max(abc.values()))
  .map(Map.Entry::getvalue)
  .collect(Collectors.toList())

0

Pour mon projet, j'ai utilisé une version légèrement modifiée de la solution de Jon et Fathah. Dans le cas d'entrées multiples avec la même valeur, il renvoie la dernière entrée qu'il trouve:

public static Entry<String, Integer> getMaxEntry(Map<String, Integer> map) {        
    Entry<String, Integer> maxEntry = null;
    Integer max = Collections.max(map.values());

    for(Entry<String, Integer> entry : map.entrySet()) {
        Integer value = entry.getValue();

        if(null != value && max == value) {
            maxEntry = entry;
        }
    }

    return maxEntry;
}

0
int maxValue = 0;
int mKey = 0;
for(Integer key: map.keySet()){
    if(map.get(key) > maxValue){
        maxValue = map.get(key);
        mKey = key;
    }
}
System.out.println("Max Value " + maxValue + " is associated with " + mKey + " key");

2
Les réponses basées uniquement sur le code sont généralement mal vues sur ce forum. Veuillez modifier votre réponse pour inclure une explication de votre code. Comment résout-il le problème d'OP?
mypetlion

-2

tu peux faire comme ça

HashMap<Integer,Integer> hm = new HashMap<Integer,Integer>();
hm.put(1,10);
hm.put(2,45);
hm.put(3,100);
Iterator<Integer> it = hm.keySet().iterator();
Integer fk = it.next();
Integer max = hm.get(fk);
while(it.hasNext()) {
    Integer k = it.next();
    Integer val = hm.get(k);
    if (val > max){
         max = val;
         fk=k;
    }
}
System.out.println("Max Value "+max+" is associated with "+fk+" key");
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.