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.

Ben B.
quelle

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

    }
}
Fathah Rehman P.
quelle
47

Ein einfacher Einzeiler mit Java-8

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

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

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

     } 
}
Soudipta Dutta
quelle
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())
Arpan Saini
quelle
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;
}
Silber
quelle
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
quelle
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");
Parnab Sanyal
quelle