20 Aralık 2018 Perşembe

Collectors groupingBy metodu - Classifier + MapFactory + Collector - Benim Belirttiğim Map Tipi Of X Haline Getirir

Giriş
Şu satırı dahil ederiz.
import static java.util.stream.Collectors.groupingBy;
groupingBy metodu - classifier yani keyMapper + mapFactory + downstream yani Collector
Metod bir Map döner.

Map nesnesinin key alanı classifier'ın döndürdüğü tiptir.
Map'in türü (örneğin TreeMap) mapFactory'nin döndürdüğü türdür.
Value alanı ise downstream'in döndürdüğü tiptir.

Classifier key değerini döner. Böylece nesneler key değerlerine göre gruplanır. Aynı key değerine sahip nesneleri downStream'e verilir.

Örnek
Elimizde şöyle bir map olsun.
Map<Integer, Long> m = ...;
Bu map'i value değerleri anahtar olarak şekilde şu hale getirmek isteyelim.
TreeMap<Long, List<Integer>> tm = ...
Şöyle yaparız.
Map<Long, List<Integer>> tm =
m.entrySet()
.stream()
.collect(Collectors.groupingBy(Map.Entry::getValue, // group the entries by the 
                                                    // value (the frequency)
   TreeMap::new, // generate a TreeMap
   Collectors.mapping (Map.Entry::getKey,
   Collectors.toList()))); // the
                           // value of the output TreeMap
                           // should be a List of the original keys
Örnek - Multiple Selection
Şöyle yaparız
List<Event> getEventsByProximityAndAffinity(int number, List<Event> events, 
                              String targetLocation, String targetType, int targetPrice) {

  Map<Integer, Map<Integer, Set<Event>>> chosenEvents = events.stream()
    .collect(groupingBy(event -> evaluateLocationProximity(event.location(), 
                                                           targetLocation), 
                        TreeMap::new,
                        groupingBy(event -> evaluateProvidersAffinity(event.eventType(), 
                                   event.price(), targetType, targetPrice), 
                                   TreeMap::new, 
                                   Collectors.toCollection(() -> 
                                   new TreeSet<>(Comparator.comparingInt(
                                                                Event::eventRankId))))));

  return chosenEvents.values()
    .stream()
    .flatMap(map -> map.values(
      .stream()
      .flatMap(Set::stream))
      limit(number)
      .collect(Collectors.toList());
}
Açıklaması şöyle
... the first Collectors::groupingBy takes the evaluateLocationProximity() as the classifying function, we generate a TreeMap to preserve order. For the downstream Collector, we use a Collectors::groupingBy using evaluateProvidersAffinity() as the classifying function with the same ordering as before.

The result is a Map<Integer, Map<Integer, Set<Event>>> where the key of the first map is the `distance’ assigned to each event and its values is another map with the key being the value of the affinity for that event and its values are the lists of events. Therefore these events correspond to a given `distance’ and `affinity’.

The final part is to return the list of events by doing a couple of flatMap(s) to extract them ordered by `distance’, `affinity’, and `rankId’.


Hiç yorum yok:

Yorum Gönder