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.

Ben B.
la source

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;
    }
}
Jon Skeet
la source
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();
Hilikus
la source
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
            }
        }

    }
}
Fathah Rehman P
la source
47

Un simple one liner utilisant Java-8

Key key = Collections.max(map.entrySet(), Map.Entry.comparingByValue()).getKey();
Sleiman Jneidi
la source
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();
Amir
la source
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);

Dave L.
la source
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()

Mariusz Szurgot
la source
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);
Jorgesys
la source
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();
}
Manas Ranjan Mahapatra
la source
A repris Baldung.com baeldung.com/java-find-map-max
Sir Montes
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);
    }
}
umeshfadadu
la source
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);
Danilo
la source
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);

     } 
}
Soudipta Dutta
la source
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())
Arpan Saini
la source
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;
}
argent
la source
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");
Abdullah Uzundere
la source
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");
Parnab Sanyal
la source