Een kaart sorteren<sleutel, waarde> op waarden

Ik ben relatief nieuw in Java en merk vaak dat ik een Map<Key, Value>op de waarden moet sorteren.

Omdat de waarden niet uniek zijn, merk ik dat ik de keySetconverteer naar een arrayen die array sorteer via array sortmet een aangepaste vergelijkerdie sorteert op de waarde die aan de sleutel is gekoppeld.

Is er een eenvoudigere manier?


Antwoord 1, autoriteit 100%

Hier is een generiek-vriendelijke versie:

public class MapUtil {
    public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
        List<Entry<K, V>> list = new ArrayList<>(map.entrySet());
        list.sort(Entry.comparingByValue());
        Map<K, V> result = new LinkedHashMap<>();
        for (Entry<K, V> entry : list) {
            result.put(entry.getKey(), entry.getValue());
        }
        return result;
    }
}

Antwoord 2, autoriteit 45%

Belangrijke opmerking:

Deze code kan op meerdere manieren breken.Als u van plan bent de verstrekte code te gebruiken, moet u ook de opmerkingen lezen om op de hoogte te zijn van de implicaties. Waarden kunnen bijvoorbeeld niet meer worden opgehaald door hun sleutel. (getgeeft altijd nullterug.)


Het lijkt veel gemakkelijker dan al het voorgaande. Gebruik een TreeMap als volgt:

public class Testing {
    public static void main(String[] args) {
        HashMap<String, Double> map = new HashMap<String, Double>();
        ValueComparator bvc = new ValueComparator(map);
        TreeMap<String, Double> sorted_map = new TreeMap<String, Double>(bvc);
        map.put("A", 99.5);
        map.put("B", 67.4);
        map.put("C", 67.4);
        map.put("D", 67.3);
        System.out.println("unsorted map: " + map);
        sorted_map.putAll(map);
        System.out.println("results: " + sorted_map);
    }
}
class ValueComparator implements Comparator<String> {
    Map<String, Double> base;
    public ValueComparator(Map<String, Double> base) {
        this.base = base;
    }
    // Note: this comparator imposes orderings that are inconsistent with
    // equals.
    public int compare(String a, String b) {
        if (base.get(a) >= base.get(b)) {
            return -1;
        } else {
            return 1;
        } // returning 0 would merge keys
    }
}

Uitvoer:

unsorted map: {D=67.3, A=99.5, B=67.4, C=67.4}
results: {D=67.3, B=67.4, C=67.4, A=99.5}

Antwoord 3, autoriteit 41%

Java 8 biedt een nieuw antwoord: converteer de items naar een stream en gebruik de comparator-combinators van Map.Entry:

Stream<Map.Entry<K,V>> sorted =
    map.entrySet().stream()
       .sorted(Map.Entry.comparingByValue());

Hiermee kunt u de items gebruiken die in oplopende volgorde van waarde zijn gesorteerd. Als u een aflopende waarde wilt, draait u de comparator gewoon om:

Stream<Map.Entry<K,V>> sorted =
    map.entrySet().stream()
       .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()));

Als de waarden niet vergelijkbaar zijn, kunt u een expliciete comparator doorgeven:

Stream<Map.Entry<K,V>> sorted =
    map.entrySet().stream()
       .sorted(Map.Entry.comparingByValue(comparator));

U kunt dan doorgaan met het gebruiken van andere streambewerkingen om de gegevens te verbruiken. Als u bijvoorbeeld de top 10 op een nieuwe kaart wilt:

Map<K,V> topTen =
    map.entrySet().stream()
       .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
       .limit(10)
       .collect(Collectors.toMap(
          Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));

Of print naar System.out:

map.entrySet().stream()
   .sorted(Map.Entry.comparingByValue())
   .forEach(System.out::println);

Antwoord 4, autoriteit 22%

Drie antwoorden van één regel…

Ik zou Google CollectionsGuaveom dit te doen – als uw waarden Comparablezijn, kunt u gebruik maken van

valueComparator = Ordering.natural().onResultOf(Functions.forMap(map))

Die een functie (object) voor de kaart zal creëren [die een van de toetsen als invoer neemt, de respectieve waarde retourneert], en er vervolgens een natuurlijke (vergelijkbare) volgorde op toepast [de waarden].

Als ze niet vergelijkbaar zijn, moet je iets doen in de trant van

valueComparator = Ordering.from(comparator).onResultOf(Functions.forMap(map)) 

Deze kunnen worden toegepast op een TreeMap (zoals OrderingComparatoruitbreidt), of een LinkedHashMap na wat sorteren

NB: Als je een TreeMap gaat gebruiken, onthoud dan dat als een vergelijking == 0, het item al in de lijst staat (wat gebeurt als je meerdere waarden hebt die de dezelfde). Om dit te verlichten, kunt u uw sleutel als volgt aan de comparator toevoegen (ervan uitgaande dat uw sleutels en waarden Comparablezijn):

valueComparator = Ordering.natural().onResultOf(Functions.forMap(map)).compound(Ordering.natural())

= Pas natuurlijke volgorde toe op de waarde die is toegewezen door de sleutel, en voeg die toe aan de natuurlijke volgorde van de sleutel

Houd er rekening mee dat dit nog steeds niet werkt als uw sleutels vergelijkbaar zijn met 0, maar dit zou voldoende moeten zijn voor de meeste comparableitems (zoals hashCode, equalsen compareTolopen vaak synchroon…)

Zie Ordering.onResultOf()en Functions.forMap().

Implementatie

Dus nu we een vergelijker hebben die doet wat we willen, moeten we er een resultaat uit halen.

map = ImmutableSortedMap.copyOf(myOriginalMap, valueComparator);

Nu zal dit waarschijnlijk werken, maar:

  1. moet gebeuren gezien een compleet afgewerkte kaart
  2. Probeer de bovenstaande vergelijkingen niet op een TreeMap; het heeft geen zin om te proberen een ingevoegde sleutel te vergelijken als deze pas na de put een waarde heeft, d.w.z. hij zal heel snel breken

Punt 1 is een beetje een dealbreaker voor mij; google collections is ongelooflijk lui (wat goed is: je kunt vrijwel elke bewerking in een oogwenk uitvoeren; het echte werk is gedaan wanneer je het resultaat gaat gebruiken), en dit vereist het kopiëren van een helekaart!

‘Volledig’ antwoord/Live gesorteerde kaart op waarden

Maak je echter geen zorgen; als je genoeg geobsedeerd was om een “live” kaart op deze manier te sorteren, zou je niet één maar beide (!) van de bovenstaande problemen kunnen oplossen met iets geks als het volgende:

Opmerking: dit is aanzienlijk veranderd in juni 2012 – de vorige code kon nooit werken: een interne HashMap is vereist om de waarden op te zoeken zonder een oneindige lus te maken tussen de TreeMap.get()-> compare()en compare()-> get()

import static org.junit.Assert.assertEquals;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import com.google.common.base.Functions;
import com.google.common.collect.Ordering;
class ValueComparableMap<K extends Comparable<K>,V> extends TreeMap<K,V> {
    //A map for doing lookups on the keys for comparison so we don't get infinite loops
    private final Map<K, V> valueMap;
    ValueComparableMap(final Ordering<? super V> partialValueOrdering) {
        this(partialValueOrdering, new HashMap<K,V>());
    }
    private ValueComparableMap(Ordering<? super V> partialValueOrdering,
            HashMap<K, V> valueMap) {
        super(partialValueOrdering //Apply the value ordering
                .onResultOf(Functions.forMap(valueMap)) //On the result of getting the value for the key from the map
                .compound(Ordering.natural())); //as well as ensuring that the keys don't get clobbered
        this.valueMap = valueMap;
    }
    public V put(K k, V v) {
        if (valueMap.containsKey(k)){
            //remove the key in the sorted set before adding the key again
            remove(k);
        }
        valueMap.put(k,v); //To get "real" unsorted values for the comparator
        return super.put(k, v); //Put it in value order
    }
    public static void main(String[] args){
        TreeMap<String, Integer> map = new ValueComparableMap<String, Integer>(Ordering.natural());
        map.put("a", 5);
        map.put("b", 1);
        map.put("c", 3);
        assertEquals("b",map.firstKey());
        assertEquals("a",map.lastKey());
        map.put("d",0);
        assertEquals("d",map.firstKey());
        //ensure it's still a map (by overwriting a key, but with a new value) 
        map.put("d", 2);
        assertEquals("b", map.firstKey());
        //Ensure multiple values do not clobber keys
        map.put("e", 2);
        assertEquals(5, map.size());
        assertEquals(2, (int) map.get("e"));
        assertEquals(2, (int) map.get("d"));
    }
 }

Als we zetten, zorgen we ervoor dat de hash-map de waarde voor de comparator heeft en zetten we deze vervolgens naar de TreeSet om te sorteren. Maar daarvoor controleren we de hash-kaart om te zien dat de sleutel niet echt een duplicaat is. De vergelijker die we maken, bevat ook de sleutel, zodat dubbele waarden de niet-dubbele sleutels niet verwijderen (vanwege == vergelijking).
Deze 2 items zijn essentieelom ervoor te zorgen dat het kaartcontract behouden blijft; als je denkt dat je dat niet wilt, dan ben je bijna op het punt om de kaart helemaal om te draaien (naar Map<V,K>).

De constructor zou moeten worden aangeroepen als

new ValueComparableMap(Ordering.natural());
 //or
 new ValueComparableMap(Ordering.from(comparator));

Antwoord 5, autoriteit 20%

Van http://www.programmersheaven.com/download/49349/download.aspx

private static <K, V> Map<K, V> sortByValue(Map<K, V> map) {
    List<Entry<K, V>> list = new LinkedList<>(map.entrySet());
    Collections.sort(list, new Comparator<Object>() {
        @SuppressWarnings("unchecked")
        public int compare(Object o1, Object o2) {
            return ((Comparable<V>) ((Map.Entry<K, V>) (o1)).getValue()).compareTo(((Map.Entry<K, V>) (o2)).getValue());
        }
    });
    Map<K, V> result = new LinkedHashMap<>();
    for (Iterator<Entry<K, V>> it = list.iterator(); it.hasNext();) {
        Map.Entry<K, V> entry = (Map.Entry<K, V>) it.next();
        result.put(entry.getKey(), entry.getValue());
    }
    return result;
}

Antwoord 6, autoriteit 8%

Met Java 8 kunt u de streamt apiom het op een aanzienlijk minder uitgebreide manier te doen:

Map<K, V> sortedMap = map.entrySet().stream()
                         .sorted(Entry.comparingByValue())
                         .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));

Antwoord 7, autoriteit 3%

Voor het sorteren van de sleutels moet de comparator elke waarde voor elke vergelijking opzoeken. Een meer schaalbare oplossing zou de entrySet rechtstreeks gebruiken, aangezien de waarde dan onmiddellijk beschikbaar zou zijn voor elke vergelijking (hoewel ik dit niet met cijfers heb ondersteund).

Hier is een algemene versie van zoiets:

public static <K, V extends Comparable<? super V>> List<K> getKeysSortedByValue(Map<K, V> map) {
    final int size = map.size();
    final List<Map.Entry<K, V>> list = new ArrayList<Map.Entry<K, V>>(size);
    list.addAll(map.entrySet());
    final ValueComparator<V> cmp = new ValueComparator<V>();
    Collections.sort(list, cmp);
    final List<K> keys = new ArrayList<K>(size);
    for (int i = 0; i < size; i++) {
        keys.set(i, list.get(i).getKey());
    }
    return keys;
}
private static final class ValueComparator<V extends Comparable<? super V>>
                                     implements Comparator<Map.Entry<?, V>> {
    public int compare(Map.Entry<?, V> o1, Map.Entry<?, V> o2) {
        return o1.getValue().compareTo(o2.getValue());
    }
}

Er zijn manieren om geheugenrotatie te verminderen voor de bovenstaande oplossing. De eerste aangemaakte ArrayList kan bijvoorbeeld opnieuw worden gebruikt als retourwaarde; dit zou onderdrukking van sommige generieke waarschuwingen vereisen, maar het kan de moeite waard zijn voor herbruikbare bibliotheekcode. Ook hoeft de vergelijker niet bij elke aanroep opnieuw te worden toegewezen.

Hier is een efficiëntere, maar minder aantrekkelijke versie:

public static <K, V extends Comparable<? super V>> List<K> getKeysSortedByValue2(Map<K, V> map) {
    final int size = map.size();
    final List reusedList = new ArrayList(size);
    final List<Map.Entry<K, V>> meView = reusedList;
    meView.addAll(map.entrySet());
    Collections.sort(meView, SINGLE);
    final List<K> keyView = reusedList;
    for (int i = 0; i < size; i++) {
        keyView.set(i, meView.get(i).getKey());
    }
    return keyView;
}
private static final Comparator SINGLE = new ValueComparator();

Ten slotte, als u voortdurend toegang wilt hebben tot de gesorteerde informatie (in plaats van deze slechts af en toe te sorteren), kunt u een extra multimap gebruiken. Laat het me weten als je meer details nodig hebt…


Antwoord 8, autoriteit 3%

De bibliotheek van commons-collections bevat een oplossing genaamd TreeBidiMap. Of u kunt de Google Collections API bekijken. Het heeft TreeMultimapdie u zou kunnen gebruiken.

En als je dit framework niet wilt gebruiken… ze worden geleverd met broncode.


Antwoord 9, autoriteit 3%

Ik heb de gegeven antwoorden bekeken, maar veel ervan zijn ingewikkelder dan nodig of verwijderen kaartelementen als meerdere sleutels dezelfde waarde hebben.

Hier is een oplossing die volgens mij beter past:

public static <K, V extends Comparable<V>> Map<K, V> sortByValues(final Map<K, V> map) {
    Comparator<K> valueComparator =  new Comparator<K>() {
        public int compare(K k1, K k2) {
            int compare = map.get(k2).compareTo(map.get(k1));
            if (compare == 0) return 1;
            else return compare;
        }
    };
    Map<K, V> sortedByValues = new TreeMap<K, V>(valueComparator);
    sortedByValues.putAll(map);
    return sortedByValues;
}

Houd er rekening mee dat de kaart is gesorteerd van de hoogste waarde naar de laagste.


Antwoord 10, autoriteit 2%

Om dit te bereiken met de nieuwe functies in Java 8:

import static java.util.Map.Entry.comparingByValue;
import static java.util.stream.Collectors.toList;
<K, V> List<Entry<K, V>> sort(Map<K, V> map, Comparator<? super V> comparator) {
    return map.entrySet().stream().sorted(comparingByValue(comparator)).collect(toList());
}

De items zijn geordend op hun waarden met behulp van de gegeven comparator. Als alternatief, als uw waarden onderling vergelijkbaar zijn, is er geen expliciete vergelijker nodig:

<K, V extends Comparable<? super V>> List<Entry<K, V>> sort(Map<K, V> map) {
    return map.entrySet().stream().sorted(comparingByValue()).collect(toList());
}

De geretourneerde lijst is een momentopname van de gegeven kaart op het moment dat deze methode wordt aangeroepen, dus geen van beide zal latere wijzigingen aan de andere weerspiegelen. Voor een live itereerbare weergave van de kaart:

<K, V extends Comparable<? super V>> Iterable<Entry<K, V>> sort(Map<K, V> map) {
    return () -> map.entrySet().stream().sorted(comparingByValue()).iterator();
}

De geretourneerde iterabele maakt elke keer dat deze wordt herhaald een nieuwe momentopname van de gegeven kaart, dus behoudens gelijktijdige wijziging, zal deze altijd de huidige staat van de kaart weergeven.


Antwoord 11, autoriteit 2%

Maak een aangepaste vergelijker en gebruik deze bij het maken van een nieuw TreeMap-object.

class MyComparator implements Comparator<Object> {
    Map<String, Integer> map;
    public MyComparator(Map<String, Integer> map) {
        this.map = map;
    }
    public int compare(Object o1, Object o2) {
        if (map.get(o2) == map.get(o1))
            return 1;
        else
            return ((Integer) map.get(o2)).compareTo((Integer)     
                                                            map.get(o1));
    }
}

Gebruik de onderstaande code in je hoofdfunctie

   Map<String, Integer> lMap = new HashMap<String, Integer>();
    lMap.put("A", 35);
    lMap.put("B", 75);
    lMap.put("C", 50);
    lMap.put("D", 50);
    MyComparator comparator = new MyComparator(lMap);
    Map<String, Integer> newMap = new TreeMap<String, Integer>(comparator);
    newMap.putAll(lMap);
    System.out.println(newMap);

Uitvoer:

{B=75, D=50, C=50, A=35}

Antwoord 12, autoriteit 2%

Gegeven kaart

  Map<String, Integer> wordCounts = new HashMap<>();
    wordCounts.put("USA", 100);
    wordCounts.put("jobs", 200);
    wordCounts.put("software", 50);
    wordCounts.put("technology", 70);
    wordCounts.put("opportunity", 200);

Sorteer de kaart op basis van de waarde in oplopende volgorde

Map<String,Integer>  sortedMap =  wordCounts.entrySet().
                                                stream().
                                                sorted(Map.Entry.comparingByValue()).
        collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
    System.out.println(sortedMap);

Sorteer de kaart op waarde in aflopende volgorde

Map<String,Integer>  sortedMapReverseOrder =  wordCounts.entrySet().
            stream().
            sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).
            collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
    System.out.println(sortedMapReverseOrder);

Uitvoer:

{software=50, technologie=70, VS=100, banen=200, kans=200}

{jobs=200, opportunity=200, VS=100, technologie=70, software=50}


Antwoord 13

Hoewel ik het ermee eens ben dat de constante noodzaak om een kaart te sorteren waarschijnlijk een geur is, denk ik dat de volgende code de gemakkelijkste manier is om dit te doen zonder een andere gegevensstructuur te gebruiken.

public class MapUtilities {
public static <K, V extends Comparable<V>> List<Entry<K, V>> sortByValue(Map<K, V> map) {
    List<Entry<K, V>> entries = new ArrayList<Entry<K, V>>(map.entrySet());
    Collections.sort(entries, new ByValue<K, V>());
    return entries;
}
private static class ByValue<K, V extends Comparable<V>> implements Comparator<Entry<K, V>> {
    public int compare(Entry<K, V> o1, Entry<K, V> o2) {
        return o1.getValue().compareTo(o2.getValue());
    }
}

}

En hier is een beschamend onvolledige eenheidstest:

public class MapUtilitiesTest extends TestCase {
public void testSorting() {
    HashMap<String, Integer> map = new HashMap<String, Integer>();
    map.put("One", 1);
    map.put("Two", 2);
    map.put("Three", 3);
    List<Map.Entry<String, Integer>> sorted = MapUtilities.sortByValue(map);
    assertEquals("First", "One", sorted.get(0).getKey());
    assertEquals("Second", "Two", sorted.get(1).getKey());
    assertEquals("Third", "Three", sorted.get(2).getKey());
}

}

Het resultaat is een gesorteerde lijst met Map.Entry-objecten, waaruit u de sleutels en waarden kunt halen.


Antwoord 14

Gebruik een algemene vergelijker zoals:

final class MapValueComparator<K,V extends Comparable<V>> implements Comparator<K> {
    private Map<K,V> map;
    private MapValueComparator() {
        super();
    }
    public MapValueComparator(Map<K,V> map) {
        this();
        this.map = map;
    }
    public int compare(K o1, K o2) {
        return map.get(o1).compareTo(map.get(o2));
    }
}

Antwoord 15

Het antwoord waarop het meest is gestemd, werkt niet als je 2 items hebt die gelijk zijn aan.
de TreeMap laat gelijke waarden weg.

het voorbeeld:
ongesorteerde kaart

sleutel/waarde: D/67,3
sleutel/waarde: A/99.5
sleutel/waarde: B/67,4
sleutel/waarde: C/67.5
sleutel/waarde: E/99.5

resultaten

sleutel/waarde: A/99.5
sleutel/waarde: C/67.5
sleutel/waarde: B/67,4
sleutel/waarde: D/67,3

Dus laat E weg!!

Voor mij werkte het prima om de comparator aan te passen, als deze gelijk is aan, retourneer dan niet 0 maar -1.

in het voorbeeld:

klasse ValueComparator implementeert Comparator {

Kaartbasis;
openbare waardevergelijker (kaartbasis) {
deze.basis = basis;
}

public int vergelijk(Object a, Object b) {

if((Double)base.get(a) < (Double)base.get(b)) {
  return 1;
} else if((Double)base.get(a) == (Double)base.get(b)) {
  return -1;
} else {
  return -1;
}

}
}

nu keert het terug:

ongesorteerde kaart:

sleutel/waarde: D/67,3
sleutel/waarde: A/99.5
sleutel/waarde: B/67,4
sleutel/waarde: C/67.5
sleutel/waarde: E/99.5

resultaten:

sleutel/waarde: A/99.5
sleutel/waarde: E/99.5
sleutel/waarde: C/67.5
sleutel/waarde: B/67,4
sleutel/waarde: D/67,3

als reactie op Aliens (2011 nov. 22):
Ik gebruik deze oplossing voor een kaart van Integer Id’s en namen, maar het idee is hetzelfde, dus misschien is de bovenstaande code niet correct (ik zal het in een test schrijven en je de juiste code geven), dit is de code voor een kaartsortering, gebaseerd op de bovenstaande oplossing:

package nl.iamit.util;
import java.util.Comparator;
import java.util.Map;
public class Comparators {
    public static class MapIntegerStringComparator implements Comparator {
        Map<Integer, String> base;
        public MapIntegerStringComparator(Map<Integer, String> base) {
            this.base = base;
        }
        public int compare(Object a, Object b) {
            int compare = ((String) base.get(a))
                    .compareTo((String) base.get(b));
            if (compare == 0) {
                return -1;
            }
            return compare;
        }
    }
}

en dit is de testklasse (ik heb hem net getest, en dit werkt voor de Integer, String Map:

package test.nl.iamit.util;
import java.util.HashMap;
import java.util.TreeMap;
import nl.iamit.util.Comparators;
import org.junit.Test;
import static org.junit.Assert.assertArrayEquals;
public class TestComparators {
    @Test
    public void testMapIntegerStringComparator(){
        HashMap<Integer, String> unSoretedMap = new HashMap<Integer, String>();
        Comparators.MapIntegerStringComparator bvc = new Comparators.MapIntegerStringComparator(
                unSoretedMap);
        TreeMap<Integer, String> sorted_map = new TreeMap<Integer, String>(bvc);
        //the testdata:
        unSoretedMap.put(new Integer(1), "E");
        unSoretedMap.put(new Integer(2), "A");
        unSoretedMap.put(new Integer(3), "E");
        unSoretedMap.put(new Integer(4), "B");
        unSoretedMap.put(new Integer(5), "F");
        sorted_map.putAll(unSoretedMap);
        Object[] targetKeys={new Integer(2),new Integer(4),new Integer(3),new Integer(1),new Integer(5) };
        Object[] currecntKeys=sorted_map.keySet().toArray();
        assertArrayEquals(targetKeys,currecntKeys);
    }
}

hier is de code voor de vergelijking van een kaart:

public static class MapStringDoubleComparator implements Comparator {
    Map<String, Double> base;
    public MapStringDoubleComparator(Map<String, Double> base) {
        this.base = base;
    }
    //note if you want decending in stead of ascending, turn around 1 and -1
    public int compare(Object a, Object b) {
        if ((Double) base.get(a) == (Double) base.get(b)) {
            return 0;
        } else if((Double) base.get(a) < (Double) base.get(b)) {
            return -1;
        }else{
            return 1;
        }
    }
}

en dit is de testcase hiervoor:

@Test
public void testMapStringDoubleComparator(){
    HashMap<String, Double> unSoretedMap = new HashMap<String, Double>();
    Comparators.MapStringDoubleComparator bvc = new Comparators.MapStringDoubleComparator(
            unSoretedMap);
    TreeMap<String, Double> sorted_map = new TreeMap<String, Double>(bvc);
    //the testdata:
    unSoretedMap.put("D",new Double(67.3));
    unSoretedMap.put("A",new Double(99.5));
    unSoretedMap.put("B",new Double(67.4));
    unSoretedMap.put("C",new Double(67.5));
    unSoretedMap.put("E",new Double(99.5));
    sorted_map.putAll(unSoretedMap);
    Object[] targetKeys={"D","B","C","E","A"};
    Object[] currecntKeys=sorted_map.keySet().toArray();
    assertArrayEquals(targetKeys,currecntKeys);
}

Natuurlijk kun je dit veel generieker maken, maar ik had het maar voor 1 geval nodig (de kaart)


Antwoord 16

In plaats van Collections.sortte gebruiken, zoals sommigen doen, raad ik aan om Arrays.sortte gebruiken. Wat Collections.sortdoet is eigenlijk zoiets als dit:

public static <T extends Comparable<? super T>> void sort(List<T> list) {
    Object[] a = list.toArray();
    Arrays.sort(a);
    ListIterator<T> i = list.listIterator();
    for (int j=0; j<a.length; j++) {
        i.next();
        i.set((T)a[j]);
    }
}

Het roept gewoon toArrayaan in de lijst en gebruikt dan Arrays.sort. Op deze manier worden alle kaartitems drie keer gekopieerd: één keer van de kaart naar de tijdelijke lijst (of het nu een LinkedList of ArrayList is), dan naar de tijdelijke array en tenslotte naar de nieuwe kaart.

Mijn oplossing slaat deze ene stap over omdat er geen onnodige LinkedList wordt gemaakt. Hier is de code, generiek-vriendelijk en prestatie-optimaal:

public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) 
{
    @SuppressWarnings("unchecked")
    Map.Entry<K,V>[] array = map.entrySet().toArray(new Map.Entry[map.size()]);
    Arrays.sort(array, new Comparator<Map.Entry<K, V>>() 
    {
        public int compare(Map.Entry<K, V> e1, Map.Entry<K, V> e2) 
        {
            return e1.getValue().compareTo(e2.getValue());
        }
    });
    Map<K, V> result = new LinkedHashMap<K, V>();
    for (Map.Entry<K, V> entry : array)
        result.put(entry.getKey(), entry.getValue());
    return result;
}

Antwoord 17

Dit is een variatie op het antwoord van Anthony, die niet werkt als er dubbele waarden zijn:

public static <K, V extends Comparable<V>> Map<K, V> sortMapByValues(final Map<K, V> map) {
    Comparator<K> valueComparator =  new Comparator<K>() {
        public int compare(K k1, K k2) {
            final V v1 = map.get(k1);
            final V v2 = map.get(k2);
            /* Not sure how to handle nulls ... */
            if (v1 == null) {
                return (v2 == null) ? 0 : 1;
            }
            int compare = v2.compareTo(v1);
            if (compare != 0)
            {
                return compare;
            }
            else
            {
                Integer h1 = k1.hashCode();
                Integer h2 = k2.hashCode();
                return h2.compareTo(h1);
            }
        }
    };
    Map<K, V> sortedByValues = new TreeMap<K, V>(valueComparator);
    sortedByValues.putAll(map);
    return sortedByValues;
}

Merk op dat het nogal in de lucht hangt hoe je met nulls omgaat.

Een belangrijk voordeel van deze aanpak is dat het in feite een kaart retourneert, in tegenstelling tot sommige van de andere oplossingen die hier worden aangeboden.


Antwoord 18

Beste aanpak

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry; 
public class OrderByValue {
  public static void main(String a[]){
    Map<String, Integer> map = new HashMap<String, Integer>();
    map.put("java", 20);
    map.put("C++", 45);
    map.put("Unix", 67);
    map.put("MAC", 26);
    map.put("Why this kolavari", 93);
    Set<Entry<String, Integer>> set = map.entrySet();
    List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(set);
    Collections.sort( list, new Comparator<Map.Entry<String, Integer>>()
    {
        public int compare( Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2 )
        {
            return (o1.getValue()).compareTo( o2.getValue() );//Ascending order
            //return (o2.getValue()).compareTo( o1.getValue() );//Descending order
        }
    } );
    for(Map.Entry<String, Integer> entry:list){
        System.out.println(entry.getKey()+" ==== "+entry.getValue());
    }
  }}

Uitvoer

java ==== 20
MAC ==== 26
C++ ==== 45
Unix ==== 67
Why this kolavari ==== 93

Antwoord 19

Groot probleem. Als u het eerste antwoord gebruikt (Google brengt u hierheen), wijzigt u de comparator om een gelijke clausule toe te voegen, anders kunt u geen waarden uit de sort_map by keys halen:

public int compare(String a, String b) {
        if (base.get(a) > base.get(b)) {
            return 1;
        } else if (base.get(a) < base.get(b)){
            return -1;
        } 
        return 0;
        // returning 0 would merge keys
    }

Antwoord 20

Er zijn al veel antwoorden op deze vraag, maar geen enkele gaf me wat ik zocht, een kaartimplementatie die sleutels en items teruggeeft die zijn gesorteerd op de bijbehorende waarde, en deze eigenschap handhaaft terwijl sleutels en waarden worden gewijzigd in de kaart. Twee anderevragenhier specifiek om vragen.

Ik heb een generiek vriendelijk voorbeeld bedacht dat deze use-case oplost. Deze implementatie voldoet niet aan alle contracten van de kaartinterface, zoals het weergeven van waardeveranderingen en verwijderingen in de sets die worden geretourneerd uit keySet() en entrySet() in het oorspronkelijke object. Ik vond dat een dergelijke oplossing te groot zou zijn om in een Stack Overflow-antwoord op te nemen. Als het me lukt om een completere implementatie te maken, zal ik deze misschien op Github plaatsen en vervolgens naar de link in een bijgewerkte versie van dit antwoord.

import java.util.*;
/**
 * A map where {@link #keySet()} and {@link #entrySet()} return sets ordered
 * by associated values based on the the comparator provided at construction
 * time. The order of two or more keys with identical values is not defined.
 * <p>
 * Several contracts of the Map interface are not satisfied by this minimal
 * implementation.
 */
public class ValueSortedMap<K, V> extends HashMap<K, V> {
    protected Map<V, Collection<K>> valueToKeysMap;
    // uses natural order of value object, if any
    public ValueSortedMap() {
        this((Comparator<? super V>) null);
    }
    public ValueSortedMap(Comparator<? super V> valueComparator) {
        this.valueToKeysMap = new TreeMap<V, Collection<K>>(valueComparator);
    }
    public boolean containsValue(Object o) {
        return valueToKeysMap.containsKey(o);
    }
    public V put(K k, V v) {
        V oldV = null;
        if (containsKey(k)) {
            oldV = get(k);
            valueToKeysMap.get(oldV).remove(k);
        }
        super.put(k, v);
        if (!valueToKeysMap.containsKey(v)) {
            Collection<K> keys = new ArrayList<K>();
            keys.add(k);
            valueToKeysMap.put(v, keys);
        } else {
            valueToKeysMap.get(v).add(k);
        }
        return oldV;
    }
    public void putAll(Map<? extends K, ? extends V> m) {
        for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
            put(e.getKey(), e.getValue());
    }
    public V remove(Object k) {
        V oldV = null;
        if (containsKey(k)) {
            oldV = get(k);
            super.remove(k);
            valueToKeysMap.get(oldV).remove(k);
        }
        return oldV;
    }
    public void clear() {
        super.clear();
        valueToKeysMap.clear();
    }
    public Set<K> keySet() {
        LinkedHashSet<K> ret = new LinkedHashSet<K>(size());
        for (V v : valueToKeysMap.keySet()) {
            Collection<K> keys = valueToKeysMap.get(v);
            ret.addAll(keys);
        }
        return ret;
    }
    public Set<Map.Entry<K, V>> entrySet() {
        LinkedHashSet<Map.Entry<K, V>> ret = new LinkedHashSet<Map.Entry<K, V>>(size());
        for (Collection<K> keys : valueToKeysMap.values()) {
            for (final K k : keys) {
                final V v = get(k);
                ret.add(new Map.Entry<K,V>() {
                    public K getKey() {
                        return k;
                    }
                    public V getValue() {
                        return v;
                    }
                    public V setValue(V v) {
                        throw new UnsupportedOperationException();
                    }
                });
            }
        }
        return ret;
    }
}

Antwoord 21

Late toegang.

Met de komst van Java-8 kunnen we streams gebruiken voor gegevensmanipulatie op een zeer gemakkelijke/korte manier. U kunt streams gebruiken om de kaartitems op waarde te sorteren en een LinkedHashMapdie insertion-orderiteratie behoudt.

Bijvoorbeeld:

LinkedHashMap sortedByValueMap = map.entrySet().stream()
                .sorted(comparing(Entry<Key,Value>::getValue).thenComparing(Entry::getKey))     //first sorting by Value, then sorting by Key(entries with same value)
                .collect(LinkedHashMap::new,(map,entry) -> map.put(entry.getKey(),entry.getValue()),LinkedHashMap::putAll);

Voor omgekeerde volgorde, vervang:

comparing(Entry<Key,Value>::getValue).thenComparing(Entry::getKey)

met

comparing(Entry<Key,Value>::getValue).thenComparing(Entry::getKey).reversed()

Antwoord 22

Afhankelijk van de context, met behulp van java.util.LinkedHashMap<T>die de volgorde onthoudt waarin items op de kaart worden geplaatst. Als u waarden moet sorteren op basis van hun natuurlijke volgorde, raad ik u aan een aparte lijst bij te houden die kan worden gesorteerd via Collections.sort().


Antwoord 23

Afaik is de meest schone manier om collecties te gebruiken om de kaart op waarde te sorteren:

Map<String, Long> map = new HashMap<String, Long>();
// populate with data to sort on Value
// use datastructure designed for sorting
Queue queue = new PriorityQueue( map.size(), new MapComparable() );
queue.addAll( map.entrySet() );
// get a sorted map
LinkedHashMap<String, Long> linkedMap = new LinkedHashMap<String, Long>();
for (Map.Entry<String, Long> entry; (entry = queue.poll())!=null;) {
    linkedMap.put(entry.getKey(), entry.getValue());
}
public static class MapComparable implements Comparator<Map.Entry<String, Long>>{
  public int compare(Entry<String, Long> e1, Entry<String, Long> e2) {
    return e1.getValue().compareTo(e2.getValue());
  }
}

Antwoord 24

Sinds TreeMap<> werkt nietvoor waarden die gelijk kunnen zijn, ik heb dit gebruikt:

private <K, V extends Comparable<? super V>> List<Entry<K, V>> sort(Map<K, V> map)     {
    List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>(map.entrySet());
    Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
        public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
            return o1.getValue().compareTo(o2.getValue());
        }
    });
    return list;
}

Misschien wil je lijstin een LinkedHashMapplaatsen, maar als je alleen gaat herhalen er meteen overheen, dat is overbodig…


Antwoord 25

Dit is gewoon te ingewikkeld. Kaarten waren niet bedoeld om zo’n werk te doen als ze op waarde te sorteren. De gemakkelijkste manier is om je eigen klas te maken, zodat deze aan je eisen voldoet.

In een lager voorbeeld zou je TreeMap een comparator moeten toevoegen op de plaats waar * is. Maar door Java API geeft het alleen comparator-sleutels, geen waarden. Alle hier genoemde voorbeelden zijn gebaseerd op 2 kaarten. Een hash en een nieuwe boom. Wat vreemd is.

Het voorbeeld:

Map<Driver driver, Float time> map = new TreeMap<Driver driver, Float time>(*);

Verander de kaart dus op deze manier in een set:

ResultComparator rc = new ResultComparator();
Set<Results> set = new TreeSet<Results>(rc);

U maakt klasse Results,

public class Results {
    private Driver driver;
    private Float time;
    public Results(Driver driver, Float time) {
        this.driver = driver;
        this.time = time;
    }
    public Float getTime() {
        return time;
    }
    public void setTime(Float time) {
        this.time = time;
    }
    public Driver getDriver() {
        return driver;
    }
    public void setDriver (Driver driver) {
        this.driver = driver;
    }
}

en de Comparator-klasse:

public class ResultsComparator implements Comparator<Results> {
    public int compare(Results t, Results t1) {
        if (t.getTime() < t1.getTime()) {
            return 1;
        } else if (t.getTime() == t1.getTime()) {
            return 0;
        } else {
            return -1;
        }
    }
}

Op deze manier kun je gemakkelijk meer afhankelijkheden toevoegen.

En als laatste punt zal ik een eenvoudige iterator toevoegen:

Iterator it = set.iterator();
while (it.hasNext()) {
    Results r = (Results)it.next();
    System.out.println( r.getDriver().toString
        //or whatever that is related to Driver class -getName() getSurname()
        + " "
        + r.getTime()
        );
}

Antwoord 26

Eenvoudige manier om elke kaart in Java 8 en hoger te sorteren

Map<String, Object> mapToSort = new HashMap<>();
List<Map.Entry<String, Object>> list = new LinkedList<>(mapToSort.entrySet());
Collections.sort(list, Comparator.comparing(o -> o.getValue().getAttribute()));
HashMap<String, Object> sortedMap = new LinkedHashMap<>();
for (Map.Entry<String, Object> map : list) {
   sortedMap.put(map.getKey(), map.getValue());
}

als u Java 7 en lager gebruikt

Map<String, Object> mapToSort = new HashMap<>();
List<Map.Entry<String, Object>> list = new LinkedList<>(mapToSort.entrySet());
Collections.sort(list, new Comparator<Map.Entry<String, Object>>() {
    @Override
    public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
       return o1.getValue().getAttribute().compareTo(o2.getValue().getAttribute());      
    }
});
HashMap<String, Object> sortedMap = new LinkedHashMap<>();
for (Map.Entry<String, Object> map : list) {
   sortedMap.put(map.getKey(), map.getValue());
}

Antwoord 27

Gebaseerd op @devinmoore-code, een kaartsorteermethode die gebruik maakt van generieke geneesmiddelen en zowel oplopende als aflopende volgorde ondersteunt.

/**
 * Sort a map by it's keys in ascending order. 
 *  
 * @return new instance of {@link LinkedHashMap} contained sorted entries of supplied map.
 * @author Maxim Veksler
 */
public static <K, V> LinkedHashMap<K, V> sortMapByKey(final Map<K, V> map) {
    return sortMapByKey(map, SortingOrder.ASCENDING);
}
/**
 * Sort a map by it's values in ascending order.
 *  
 * @return new instance of {@link LinkedHashMap} contained sorted entries of supplied map.
 * @author Maxim Veksler
 */
public static <K, V> LinkedHashMap<K, V> sortMapByValue(final Map<K, V> map) {
    return sortMapByValue(map, SortingOrder.ASCENDING);
}
/**
 * Sort a map by it's keys.
 *  
 * @param sortingOrder {@link SortingOrder} enum specifying requested sorting order. 
 * @return new instance of {@link LinkedHashMap} contained sorted entries of supplied map.
 * @author Maxim Veksler
 */
public static <K, V> LinkedHashMap<K, V> sortMapByKey(final Map<K, V> map, final SortingOrder sortingOrder) {
    Comparator<Map.Entry<K, V>> comparator = new Comparator<Entry<K,V>>() {
        public int compare(Entry<K, V> o1, Entry<K, V> o2) {
            return comparableCompare(o1.getKey(), o2.getKey(), sortingOrder);
        }
    };
    return sortMap(map, comparator);
}
/**
 * Sort a map by it's values.
 *  
 * @param sortingOrder {@link SortingOrder} enum specifying requested sorting order. 
 * @return new instance of {@link LinkedHashMap} contained sorted entries of supplied map.
 * @author Maxim Veksler
 */
public static <K, V> LinkedHashMap<K, V> sortMapByValue(final Map<K, V> map, final SortingOrder sortingOrder) {
    Comparator<Map.Entry<K, V>> comparator = new Comparator<Entry<K,V>>() {
        public int compare(Entry<K, V> o1, Entry<K, V> o2) {
            return comparableCompare(o1.getValue(), o2.getValue(), sortingOrder);
        }
    };
    return sortMap(map, comparator);
}
@SuppressWarnings("unchecked")
private static <T> int comparableCompare(T o1, T o2, SortingOrder sortingOrder) {
    int compare = ((Comparable<T>)o1).compareTo(o2);
    switch (sortingOrder) {
    case ASCENDING:
        return compare;
    case DESCENDING:
        return (-1) * compare;
    }
    return 0;
}
/**
 * Sort a map by supplied comparator logic.
 *  
 * @return new instance of {@link LinkedHashMap} contained sorted entries of supplied map.
 * @author Maxim Veksler
 */
public static <K, V> LinkedHashMap<K, V> sortMap(final Map<K, V> map, final Comparator<Map.Entry<K, V>> comparator) {
    // Convert the map into a list of key,value pairs.
    List<Map.Entry<K, V>> mapEntries = new LinkedList<Map.Entry<K, V>>(map.entrySet());
    // Sort the converted list according to supplied comparator.
    Collections.sort(mapEntries, comparator);
    // Build a new ordered map, containing the same entries as the old map.  
    LinkedHashMap<K, V> result = new LinkedHashMap<K, V>(map.size() + (map.size() / 20));
    for(Map.Entry<K, V> entry : mapEntries) {
        // We iterate on the mapEntries list which is sorted by the comparator putting new entries into 
        // the targeted result which is a sorted map. 
        result.put(entry.getKey(), entry.getValue());
    }
    return result;
}
/**
 * Sorting order enum, specifying request result sort behavior.
 * @author Maxim Veksler
 *
 */
public static enum SortingOrder {
    /**
     * Resulting sort will be from smaller to biggest.
     */
    ASCENDING,
    /**
     * Resulting sort will be from biggest to smallest.
     */
    DESCENDING
}

Antwoord 28

Hier is een OO-oplossing (d.w.z. gebruikt geen staticmethoden):

import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class SortableValueMap<K, V extends Comparable<V>>
  extends LinkedHashMap<K, V> {
  public SortableValueMap() { }
  public SortableValueMap( Map<K, V> map ) {
    super( map );
  }
  public void sortByValue() {
    List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>( entrySet() );
    Collections.sort( list, new Comparator<Map.Entry<K, V>>() {
      public int compare( Map.Entry<K, V> entry1, Map.Entry<K, V> entry2 ) {
        return entry1.getValue().compareTo( entry2.getValue() );
      }
    });
    clear();
    for( Map.Entry<K, V> entry : list ) {
      put( entry.getKey(), entry.getValue() );
    }
  }
  private static void print( String text, Map<String, Double> map ) {
    System.out.println( text );
    for( String key : map.keySet() ) {
      System.out.println( "key/value: " + key + "/" + map.get( key ) );
    }
  }
  public static void main( String[] args ) {
    SortableValueMap<String, Double> map =
      new SortableValueMap<String, Double>();
    map.put( "A", 67.5 );
    map.put( "B", 99.5 );
    map.put( "C", 82.4 );
    map.put( "D", 42.0 );
    print( "Unsorted map", map );
    map.sortByValue();
    print( "Sorted map", map );
  }
}

Hierbij gedoneerd aan het publieke domein.


Antwoord 29

Enkele eenvoudige wijzigingen om een gesorteerde kaart te hebben met paren die dubbele waarden hebben. In de vergelijkingsmethode (klasse ValueComparator) wanneer waarden gelijk zijn, retourneert u niet 0 maar retourneert u het resultaat van het vergelijken van de 2 sleutels. Sleutels zijn verschillend in een kaart, zodat u dubbele waarden kunt behouden (die overigens op sleutels zijn gesorteerd). Dus het bovenstaande voorbeeld kan als volgt worden gewijzigd:

   public int compare(Object a, Object b) {
        if((Double)base.get(a) < (Double)base.get(b)) {
          return 1;
        } else if((Double)base.get(a) == (Double)base.get(b)) {
          return ((String)a).compareTo((String)b);
        } else {
          return -1;
        }
      }
    }

Antwoord 30

De oplossing van Stephen is zeker geweldig, maar voor degenen die Guava niet kunnen gebruiken:

Hier is mijn oplossing voor het sorteren op waarde van een kaart.
Deze oplossing behandelt het geval waarin er twee keer dezelfde waarde is, enz…

// If you want to sort a map by value, and if there can be twice the same value:
// here is your original map
Map<String,Integer> mapToSortByValue = new HashMap<String, Integer>();
mapToSortByValue.put("A", 3);
mapToSortByValue.put("B", 1);
mapToSortByValue.put("C", 3);
mapToSortByValue.put("D", 5);
mapToSortByValue.put("E", -1);
mapToSortByValue.put("F", 1000);
mapToSortByValue.put("G", 79);
mapToSortByValue.put("H", 15);
// Sort all the map entries by value
Set<Map.Entry<String,Integer>> set = new TreeSet<Map.Entry<String,Integer>>(
        new Comparator<Map.Entry<String,Integer>>(){
            @Override
            public int compare(Map.Entry<String,Integer> obj1, Map.Entry<String,Integer> obj2) {
                Integer val1 = obj1.getValue();
                Integer val2 = obj2.getValue();
                // DUPLICATE VALUE CASE
                // If the values are equals, we can't return 0 because the 2 entries would be considered
                // as equals and one of them would be deleted (because we use a set, no duplicate, remember!)
                int compareValues = val1.compareTo(val2);
                if ( compareValues == 0 ) {
                    String key1 = obj1.getKey();
                    String key2 = obj2.getKey();
                    int compareKeys = key1.compareTo(key2);
                    if ( compareKeys == 0 ) {
                        // what you return here will tell us if you keep REAL KEY-VALUE duplicates in your set
                        // if you want to, do whatever you want but do not return 0 (but don't break the comparator contract!)
                        return 0;
                    }
                    return compareKeys;
                }
                return compareValues;
            }
        }
);
set.addAll(mapToSortByValue.entrySet());
// OK NOW OUR SET IS SORTED COOL!!!!
// And there's nothing more to do: the entries are sorted by value!
for ( Map.Entry<String,Integer> entry : set ) {
    System.out.println("Set entries: " + entry.getKey() + " -> " + entry.getValue());
}
// But if you add them to an hashmap
Map<String,Integer> myMap = new HashMap<String,Integer>();
// When iterating over the set the order is still good in the println...
for ( Map.Entry<String,Integer> entry : set ) {
    System.out.println("Added to result map entries: " + entry.getKey() + " " + entry.getValue());
    myMap.put(entry.getKey(), entry.getValue());
}
// But once they are in the hashmap, the order is not kept!
for ( Integer value : myMap.values() ) {
    System.out.println("Result map values: " + value);
}
// Also this way doesn't work:
// Logic because the entryset is a hashset for hashmaps and not a treeset
// (and even if it was a treeset, it would be on the keys only)
for ( Map.Entry<String,Integer> entry : myMap.entrySet() ) {
    System.out.println("Result map entries: " + entry.getKey() + " -> " + entry.getValue());
}
// CONCLUSION:
// If you want to iterate on a map ordered by value, you need to remember:
// 1) Maps are only sorted by keys, so you can't sort them directly by value
// 2) So you simply CAN'T return a map to a sortMapByValue function
// 3) You can't reverse the keys and the values because you have duplicate values
//    This also means you can't neither use Guava/Commons bidirectionnal treemaps or stuff like that
// SOLUTIONS
// So you can:
// 1) only sort the values which is easy, but you loose the key/value link (since you have duplicate values)
// 2) sort the map entries, but don't forget to handle the duplicate value case (like i did)
// 3) if you really need to return a map, use a LinkedHashMap which keep the insertion order

De directeur:
http://www.ideone.com/dq3Lu

De uitvoer:

Set entries: E -> -1
Set entries: B -> 1
Set entries: A -> 3
Set entries: C -> 3
Set entries: D -> 5
Set entries: H -> 15
Set entries: G -> 79
Set entries: F -> 1000
Added to result map entries: E -1
Added to result map entries: B 1
Added to result map entries: A 3
Added to result map entries: C 3
Added to result map entries: D 5
Added to result map entries: H 15
Added to result map entries: G 79
Added to result map entries: F 1000
Result map values: 5
Result map values: -1
Result map values: 1000
Result map values: 79
Result map values: 3
Result map values: 1
Result map values: 3
Result map values: 15
Result map entries: D -> 5
Result map entries: E -> -1
Result map entries: F -> 1000
Result map entries: G -> 79
Result map entries: A -> 3
Result map entries: B -> 1
Result map entries: C -> 3
Result map entries: H -> 15

Ik hoop dat het sommige mensen zal helpen

Other episodes