2015-05-24 8 views
36

Ho la mappa Map<Type, Long> countByType e voglio avere una lista che ha ordinato i tasti (da minimo a massimo) con i loro valori corrispondenti. La mia prova è:Java 8 stream map alla lista di chiavi ordinate per valori

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

tuttavia questo mi dà un elenco di voci, come posso ottenere un elenco di tipi, senza perdere l'ordine?

risposta

85

Si dice di voler ordinare per valore, ma non lo si ha nel codice. Passa una lambda (o metodo di riferimento) a sorted per dirgli come vuoi ordinare.

E si desidera ottenere le chiavi; utilizzare map per trasformare le voci in chiavi.

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

... o '.sorted (Map.Entry.comparingByValue())' –

+0

Dopo il concatenamento 'sorted' come posso ottenere il flusso di nuovo ad un carta geografica? Beh, tecnicamente so che non potrei tornare su una mappa perché i suoi set non sono ordinati. Ma vorrei stampare la mappa in questo modo '.forEach ((k, v) -> System.out.println (k +": "+ v)'. Come posso ottenere questo usando quel flusso? – dabadaba

+0

@dabadaba dopo il '.sorted (...)' hai un flusso di voci, quindi potresti aggiungere '.forEach (e -> System.out.println (e.getKey() +": "+ e.getValue())) – Jesper

9

È necessario ordinare con un comparatore personalizzato in base al valore della voce. Quindi seleziona tutti i tasti prima della raccolta

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

È possibile ordinare una mappa per valore come sotto, altro esempio 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

Ecco la soluzione semplice, con 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()); 

uscita: [A, B, C, D]

0

È possibile utilizzare questo come un esempio del problema

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