quoi Comment trier la carte de hachage en fonction du nombre de clés pour une valeur en utilisant flatmap java8?



wikipedia table de hachage (1)

Ceci est un suivi de Comment obtenir le nombre de clés pour les valeurs dans une carte de hachage en utilisant lambda . J'ai une HashMap et je veux trouver le nombre de clés pour chaque valeur

Map<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>() {{
    put(0, Arrays.asList(1, 2));
    put(1, Arrays.asList(2, 0, 3));
    put(2, Arrays.asList(4,0,1));
    put(3, Arrays.asList(4,1, 5));
    put(4, Arrays.asList(5,2,3));
    put(5, Arrays.asList(4,3));
}};

Selon le post ci-dessus, j'ai essayé la cartographie plate:

Map<Object, Long> ex = 
                map.values()
                .stream()
                .flatMap(Collection::stream)
                .collect(Collectors.groupingBy(v -> v, Collectors.counting()));

System.out.println(ex);

La sortie est

{0=2, 1=3, 2=3, 3=3, 4=3, 5=2}. 

Cela signifie que 0 a deux touches, 1 a trois touches et ainsi de suite. Maintenant, je veux trier les clés et les valeurs dans l'ordre décroissant en fonction du nombre de clés. J'ai essayé quelque chose comme ça:

Map<Object, Long> ex = 
                map.values()
                .stream()
                .flatMap(Collection::stream)
                .collect(Collectors.groupingBy(v -> v, Collectors.counting()));

                        .entrySet()
                        .stream()
                        .sorted(Map.Entry.<String, Long>comparingByValue(reverseOrder()).thenComparing(Map.Entry.comparingByKey()))
                        .collect(LinkedHashMap::new, (m,e) -> m.put(e.getKey(), e.getValue()), Map::putAll);

Je veux la sortie suivante:

1=[2, 3, 0], 2=[1,4,0], 3=[1, 4, 5], 4=[2, 3, 5], 0=[1, 2], 5=[3, 4]

Les clés et les valeurs doivent être disposées en descendant en fonction de ce nombre de clés {0=2, 1=3, 2=3, 3=3, 4=3, 5=2} : 1, 2, 3, 4 a trois Les touches 0 et 5 ont deux touches.

Par exemple: 1=[2, 3, 0] : 1 a trois touches donc il apparaît d'abord avec [2, 3, 0] : 2 et 3 ont trois touches et 0 a seulement deux touches.


Vous pourriez avoir ce qui suit:

Map<Integer, List<Integer>> sorted = 
    map.entrySet()
       .stream()
       .sorted(comparing(e -> ex.get(e.getKey()), reverseOrder()))
       .collect(toMap(
           Map.Entry::getKey,
           e -> e.getValue().stream().sorted(comparing(ex::get, reverseOrder())).collect(toList()),
           (v1, v2) -> { throw new IllegalStateException(); },
           LinkedHashMap::new
       ));

Cela crée un flux des entrées de la carte, les trie dans l'ordre inverse en fonction du nombre de clés pour la clé de cette entrée et finalement la collecte dans une carte où la nouvelle valeur est triée dans l'ordre inverse du nombre de chaque entier ( ex::get ). La carte de collecte est une LinkedHashMap pour préserver l'ordre de rencontre.

Sortie:

{1=[2, 3, 0], 2=[4, 1, 0], 3=[4, 1, 5], 4=[2, 3, 5], 0=[1, 2], 5=[4, 3]}

Importations statiques utilisées:

import static java.util.Comparator.comparing;
import static java.util.Comparator.reverseOrder;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toMap;




java-stream