
Originariamente inviata da
fermat
codice:
public <K, V extends Comparable<V>> Map<K, V> sortByValues(Map<K, V> map) {
Comparator<K> valueComparator = (k1, k2) -> {
int compare = map.get(k2).compareTo(map.get(k1));
return (compare == 0) ? 1 : compare;
};
Map<K, V> sortedByValues = new TreeMap<>(valueComparator);
sortedByValues.putAll(map);
System.out.println(map);
System.out.println(sortedByValues);
return sortedByValues;
}
Non è molto bello ..... dico il fatto innanzitutto di accedere alla map (il parametro) che è fuori dalla lambda (quindi come effetto "collaterale") ed anche il fatto che il Comparator (che in realtà è sulle chiavi!!) vada a fare il truschino di confrontare i valori.
Si può fare con gli stream. Guarda questo esempio:
codice:
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Prova {
public static void main(String[] args) {
List<Persona> persone = Arrays.asList(
new Persona("Andrea"), new Persona("Mario"),
new Persona("Laura"), new Persona("Andrea"),
new Persona("Paola"), new Persona("Mario"),
new Persona("Andrea"));
Map<String,Long> mapNomeConteggio = persone.stream()
.collect(Collectors.groupingBy(Persona::getNome, Collectors.counting()));
System.out.println(mapNomeConteggio);
Map<Long,List<String>> mapConteggioNomi = mapNomeConteggio.entrySet().stream()
.collect(Collectors.groupingBy(Map.Entry::getValue, TreeMap::new,
Collectors.mapping(Map.Entry::getKey, Collectors.toList())));
System.out.println(mapConteggioNomi);
}
}
class Persona {
private final String nome;
public Persona(String nome) {
this.nome = nome;
}
public String getNome() {
return nome;
}
}
Nota che il 2° parametro del groupingBy è un Supplier<M> mapFactory che serve per fornire la map, che sopra è un TreeMap.
Osserva l'output dei due println.