Suchen des Schlüssels, der dem Maximalwert in einer Java Map zugeordnet ist


137

Was ist der einfachste Weg, um den Schlüssel mit dem Maximalwert in einer Karte zu verknüpfen?

Ich glaube, dass Collections.max (someMap) den maximalen Schlüssel zurückgibt, wenn Sie den Schlüssel möchten, der dem maximalen Wert entspricht.

Antworten:


136

Grundsätzlich müssten Sie den Eintragssatz der Karte durchlaufen und sich dabei sowohl das "derzeit bekannte Maximum" als auch den damit verbundenen Schlüssel merken. (Oder natürlich nur der Eintrag, der beides enthält.)

Beispielsweise:

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: Sie können mehr als einen Schlüssel mit demselben Maximalwert haben. Diese Schleife gibt Ihnen die erste, die sie findet.
Peter Lawrey

21
Wenn Sie> 0 in> = 0 ändern, erhalten Sie den letzten gefundenen
Aaron J Lang

1
Würde die Verwendung von Java 8-Streams dazu beitragen, dies weiter zu vereinfachen? Beispiel: map.forEach ((k, v) -> ...
zkarthik

3
@zkarthik: Die Verwendung maxmit einem benutzerdefinierten Komparator wäre wahrscheinlich einfacher.
Jon Skeet

112

Der Vollständigkeit halber hier ein Art und Weise, es zu tun

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

oder

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

oder

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

3
(entry1, entry2) -> entry1.getValue() - entry2.getValue()ist kompakter für den Komparator.
JustABit

5
Was tun, wenn alle Schlüssel dem Maximalwert entsprechen sollen?
Mouna

4
Kompakt aber schwer zu verstehen.
Lluis Martinez

1
Sie können auch die Vergleichsmethode der Integer-Klasse verwendencountMap.entrySet().stream().max((entry1, entry2) -> Integer.compare(entry1.getValue(), entry2.getValue())).get().getKey();
Rui Filipe Pedro

3
Oder Sie können Map.Entry.comparingByValue()stattdessen verwenden
Alexey Grigorev

53

Dieser Code druckt alle Schlüssel mit dem Maximalwert

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

Ein einfacher Einzeiler mit Java-8

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


3
Eleganteste und minimalistischste Lösung. Danke
Daniel Hári

@ Samir, bitte überprüfen Sie Ihre Java-Version. Sleiman Jneid hat ausdrücklich erwähnt, dass es mit Java 8
Vaibs

@ Vaibs Ich habe Java 8 verwendet. Es spielt keine Rolle mehr, Hilikus 'Antwort hat bei mir funktioniert.
Samir

Es funktioniert für mich so: String max_key = Collections.max(map.entrySet(), Map.Entry.comparingByValue()).getKey();
Timur Nurlygayanov

8

So geht's direkt (ohne explizite zusätzliche Schleife), indem Sie das entsprechende definieren 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

Eine Antwort, die eine Option zurückgibt, da die Karte möglicherweise keinen Maximalwert hat, wenn sie leer ist: map.entrySet().stream().max(Map.Entry.comparingByValue()).map(Map.Entry::getKey);


4

Java 8 Weg, um alle Schlüssel mit maximalem Wert zu erhalten.

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

Sie können es auch parallelisieren, indem Sie parallelStream()anstelle von verwendenstream()


4

Ich habe zwei Methoden, um mit dieser Methode den Schlüssel mit dem Maximalwert zu erhalten:

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

Als Beispiel erhalten Sie den Eintrag mit dem Maximalwert mithilfe der folgenden Methode:

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

Mit Java 8 können wir ein Objekt erhalten, das den Maximalwert enthält:

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

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

Die Java 8-Version ist einfach, aber effektiv!
Gute

3

1. Verwenden von 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. Verwenden von Collections.max () mit einem Lambda-Ausdruck

    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. Verwenden von Stream mit Methodenreferenz

    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. Verwenden von 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. Verwenden der einfachen Iteration

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

Einfach zu verstehen. Im folgenden Code ist maxKey der Schlüssel, der den Maximalwert enthält.

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

1

Ist diese Lösung in Ordnung?

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

Mehrheitselement / Max-Element in der Karte:

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

gegebene Karte

HashMap abc = new HashMap <> ();

Holen Sie sich alle Karteneinträge mit maximal Werten.

Sie können eine der folgenden Methoden im Filter verwenden, um entsprechende Karteneinträge für Sätze von Minimal- oder Maximalwerten abzurufen

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

wenn Sie nur die Schlüssel für die Filterkarte erhalten möchten

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

Wenn Sie die Werte für die gefilterte Karte erhalten möchten

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

Wenn Sie alle diese Schlüssel in eine Liste aufnehmen möchten:

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

Wenn Sie alle diese Werte in einer Liste erhalten möchten:

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

0

Für mein Projekt habe ich eine leicht modifizierte Version der Lösung von Jon und Fathah verwendet. Bei mehreren Einträgen mit demselben Wert wird der zuletzt gefundene Eintrag zurückgegeben:

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
Nur-Code-Antworten werden in diesem Forum im Allgemeinen verpönt. Bitte bearbeiten Sie Ihre Antwort, um eine Erklärung Ihres Codes aufzunehmen. Wie löst es das Problem von OP?
Mypetlion

-2

das kannst du so machen

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");
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.