Krzysztof Tkacz
Krzysztof Tkacz

Reputation: 488

Java, grouping, sorting and collecting maps using streams

I've got two Maps of shops, I'd like to count how many shops of each brand there is in that first Map, but the brands, are available only in second Map. Then I want to sort my results by descending number of shops of each brand. My code looks like this:

Store store, store1, store2, store3, store4, store5, store6;
store = new Store("1", null);
store1 = new Store("2", null);
store2 = new Store("3", null);
Map<String, Store> dynamicShops = new HashMap<>();
dynamicShops.put(store.getId(), store);
dynamicShops.put(store1.getId(), store1);
dynamicShops.put(store2.getId(), store2);

store3 = new Store("1", "ABC");
store4 = new Store("2", "ABC");
store5 = new Store("3", "Abra Cadabra");
store6 = new Store("4", "Abra Cadabra");
Map<String, Store> staticShops = new HashMap<>();
staticShops.put(store3.getId(), store3);
staticShops.put(store4.getId(), store4);
staticShops.put(store5.getId(), store5);
staticShops.put(store6.getId(), store6);

Map<String, Long> stats = dynamicShops.values().stream()
            .collect(groupingBy(s -> staticShops.get(s.getId()).getBrand(), counting()));

Map<String, Long> statsSorted = stats.entrySet().stream()
            .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
            .collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));

statsSorted.entrySet().stream().forEach(s -> System.out.println(s.getKey() + " " + s.getValue()));

And produces output I'm expecting:

ABC 2
Abra Cadabra 1

Now I'm wondering is there a way to accompish it in one stream?

Upvotes: 0

Views: 122

Answers (1)

Eng.Fouad
Eng.Fouad

Reputation: 117587

Here is one solution:

dynamicShops.values()
            .stream()
            .map(s -> staticShops.get(s.getId()).getBrand())
            .collect(Collectors.collectingAndThen(Collectors.groupingBy(Function.identity(), Collectors.counting()), m -> m.entrySet().stream()))
            .sorted(Entry.<String, Long>comparingByValue().reversed())
            .forEach(s -> System.out.println(s.getKey() + " " + s.getValue()));

Upvotes: 2

Related Questions