Individuazione della chiave associata al valore massimo in una mappa Java


137

Qual è il modo più semplice per ottenere la chiave associata al valore massimo in una mappa?

Credo che Collections.max (someMap) restituirà la chiave massima, quando si desidera la chiave che corrisponde al valore massimo.

Risposte:


136

Fondamentalmente dovresti iterare sul set di voci della mappa, ricordando sia il "massimo attualmente noto" sia la chiave ad esso associata. (O solo la voce contenente entrambi, ovviamente.)

Per esempio:

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: puoi avere più di una chiave con lo stesso valore massimo. Questo loop ti darà il primo che trova.
Peter Lawrey,

21
Cambiando> 0 in> = 0 ti darà l'ultimo trovato
Aaron J Lang

1
L'utilizzo degli stream Java 8 sarebbe di aiuto nel semplificare questo aspetto? es: map.forEach ((k, v) -> ...
zkarthik,

3
@zkarthik: l'utilizzo maxcon un comparatore personalizzato sarebbe probabilmente più semplice.
Jon Skeet,

112

Per completezza, ecco a modo di farlo

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

o

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

o

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

3
(entry1, entry2) -> entry1.getValue() - entry2.getValue()è più compatto per il comparatore.
JustABit,

5
Cosa fare se desidero tutte le chiavi che corrispondono al valore massimo?
Mouna,

4
Compatto ma difficile da capire.
Lluis Martinez,

1
Puoi anche usare il metodo di confronto fornito dalla classe IntegercountMap.entrySet().stream().max((entry1, entry2) -> Integer.compare(entry1.getValue(), entry2.getValue())).get().getKey();
Rui Filipe Pedro,

3
Oppure puoi usare Map.Entry.comparingByValue()invece
Alexey Grigorev,

55

Questo codice stamperà tutte le chiavi con il valore massimo

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 semplice liner che utilizza Java-8

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


3
La soluzione più elegante e minimale. Grazie
Daniel Hári il

@ Samir, controlla la tua versione Java. Sleiman Jneid ha esplicitamente menzionato che funzionerà con Java 8
Vaibs,

@Vaibs Stavo usando Java 8. Non importa più, la risposta di Hilikus ha funzionato per me.
Samir,

Funziona così: String max_key = Collections.max(map.entrySet(), Map.Entry.comparingByValue()).getKey();
Timur Nurlygayanov,

8

Ecco come farlo direttamente (senza un loop aggiuntivo esplicito) definendo l'appropriato 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

Una risposta che restituisce un facoltativo poiché la mappa potrebbe non avere un valore massimo se è vuota: map.entrySet().stream().max(Map.Entry.comparingByValue()).map(Map.Entry::getKey);


4

Java 8 modo per ottenere tutte le chiavi con valore massimo.

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);

Inoltre puoi parallelizzare usando parallelStream()invece distream()


4

Ho due metodi, usando questo metodo per ottenere la chiave con il valore massimo:

 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;
}

Ad esempio, accedere alla voce con il valore massimo utilizzando il metodo:

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

Usando Java 8 possiamo ottenere un oggetto contenente il valore massimo:

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

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

La versione java 8 è semplice ma efficace! Bel lavoro
Catbuilt

3

1. Utilizzo di 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. Utilizzo di Collections.max () con un'espressione 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. Utilizzo di Stream con metodo di riferimento

    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. Utilizzo di 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. Utilizzo di Iterazione semplice

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

Ho assunto Baldung.com baeldung.com/java-find-map-max
Sir Montes

2

Semplice da capire Nel codice sottostante, maxKey è la chiave che contiene il valore massimo.

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

1

Questa soluzione è ok?

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

Elemento di maggioranza / elemento massimo nella mappa:

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

data mappa

HashMap abc = new HashMap <> ();

ottenere tutte le voci della mappa con un massimo di valori.

puoi utilizzare uno dei metodi seguenti nel filtro per ottenere le rispettive voci della mappa per insiemi di valori minimi o massimi

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()))

se solo volessi ottenere le chiavi per la mappa del filtro

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

se vuoi ottenere i valori per la mappa filtrata

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

se vuoi ottenere tutte queste chiavi in ​​un elenco:

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

se si desidera ottenere tutti questi valori in un elenco:

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

0

Per il mio progetto, ho usato una versione leggermente modificata della soluzione di Jon e Fathah. Nel caso di più voci con lo stesso valore, restituisce l'ultima voce trovata:

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
Le risposte solo al codice sono generalmente disapprovate su questo forum. Modifica la tua risposta per includere una spiegazione del tuo codice. Come risolve il problema di OP?
mypetlion il

-2

puoi fare così

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");
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.