2015-05-24 4 views
36

Ich habe Karte Map<Type, Long> countByType und ich möchte eine Liste, die (min bis max) Tasten durch ihre entsprechenden Werte sortiert haben. Mein Versuch ist:Java 8 Stream Karte zu Liste der Schlüssel nach Werten sortiert

countByType.entrySet().stream().sorted().collect(Collectors.toList()); 

aber das gibt mir nur eine Liste von Einträgen, wie kann ich eine Liste der Arten zu erhalten, ohne den Auftrag zu verlieren?

Antwort

85

Sie sagen, dass Sie nach Wert sortieren möchten, aber Sie haben das nicht in Ihrem Code. Übergeben Sie ein Lambda (oder eine Methodenreferenz) an sorted, um ihm mitzuteilen, wie Sie sortieren möchten.

Und Sie möchten die Schlüssel erhalten; Verwenden Sie map, um Einträge in Schlüssel umzuwandeln.

List<Type> types = countByType.entrySet().stream() 
     .sorted(Comparator.comparing(Map.Entry::getValue)) 
     .map(Map.Entry::getKey) 
     .collect(Collectors.toList()); 
+33

... oder 'verwenden .sorted (Map.Entry.comparingByValue())' –

+0

Nach Verkettungs 'sorted' wie kann ich den Strom wieder in eine bekommen Karte? Nun, ich weiß technisch, dass ich es nicht auf eine Karte zurücksetzen konnte, weil seine Sets nicht geordnet sind. Aber ich möchte die Karte wie folgt drucken: .forEach ((k, v) -> System.out.println (k + ":" + v) '. Wie kann ich dies mit diesem Stream erreichen? – dabadaba

+0

@dabadaba nach die '.sorted (...)' haben Sie einen Strom von Einträgen, so dass Sie '.forEach (e -> System.out.println (e.getKey() +": "+ e.getValue())); ' – Jesper

9

Sie müssen mit einem benutzerdefinierten Komparator basierend auf dem Wert des Eintrags sortieren. Dann wählen Sie alle Schlüssel vor dem Sammeln

countByType.entrySet() 
      .stream() 
      .sorted((e1, e2) -> e1.getValue().compareTo(e2.getValue())) // custom Comparator 
      .map(e -> e.getKey()) 
      .collect(Collectors.toList()); 
3

Sie können wie unten eine Karte von Wert sortieren, mehr Beispiel here

//Sort a Map by their Value. 
Map<Integer, String> random = new HashMap<Integer, String>(); 

random.put(1,"z"); 
random.put(6,"k"); 
random.put(5,"a"); 
random.put(3,"f"); 
random.put(9,"c"); 

Map<Integer, String> sortedMap = 
     random.entrySet().stream() 
       .sorted(Map.Entry.comparingByValue()) 
       .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, 
         (e1, e2) -> e2, LinkedHashMap::new)); 
System.out.println("Sorted Map: " + Arrays.toString(sortedMap.entrySet().toArray())); 
0

Hier ist die einfache Lösung mit StreamEx

EntryStream.of(countByType).sortedBy(e -> e.getValue()).keys().toList(); 
2
Map<Integer, String> map = new HashMap<>(); 
    map.put(1, "B"); 
    map.put(2, "C"); 
    map.put(3, "D"); 
    map.put(4, "A"); 

    List<String> list = map.values().stream() 
      .sorted() 
      .collect(Collectors.toList()); 

Ausgang ist: [A, B, C, D]

0

Sie können dies als ein Beispiel für Ihr Problem

Map<Integer, String> map = new HashMap<>(); 
    map.put(10, "apple"); 
    map.put(20, "orange"); 
    map.put(30, "banana"); 
    map.put(40, "watermelon"); 
    map.put(50, "dragonfruit"); 

    // split a map into 2 List 
    List<Integer> resultSortedKey = new ArrayList<>(); 
    List<String> resultValues = map.entrySet().stream() 
      //sort a Map by key and stored in resultSortedKey 
      .sorted(Map.Entry.<Integer, String>comparingByKey().reversed()) 
      .peek(e -> resultSortedKey.add(e.getKey())) 
      .map(x -> x.getValue()) 
      // filter banana and return it to resultValues 
      .filter(x -> !"banana".equalsIgnoreCase(x)) 
      .collect(Collectors.toList()); 

    resultSortedKey.forEach(System.out::println); 
    resultValues.forEach(System.out::println);