2016-01-11 40 views
11

Ben Map<A, Map<B, C>> var ve Java akışları kullanarak ondan Map<B, List<C>> almak istediğiniz anahtar iç harita göre gruplandırılmış olsun.Java Akışları: Değerler

public <A, B, C> Map<B, List<C>> groupsByInnerKey(Map<A, Map<B, C>> input) { 
    return input.values() 
      .stream() 
      .flatMap(it -> it.entrySet().stream()) 
      .collect(Collectors.groupingBy(Map.Entry::getKey)); 
} 

beklediğim Ne:

  • flatMap bir StreamMap.Entry<B, C>
  • collect(Collectors.groupingBy(...))Map.Entry<B, C> uygulanan ve B döndürür işlevi alır ait verir, şöyle

    bunu yapmaya çalışacağım Böylece C'un değerlerini List<C> içine toplar.

Ama anlamıyla, derleme değil:

Olmayan statik yöntem son satırında Map.Entry::getKey statik bir bağlamda

başvurulan edilemez.

birisi yanlış ya İstediğimi elde etmek için doğru yolu nedir nedir açıklayabilir misiniz?

+0

Olası yinelenen: http://stackoverflow.com/questions/29373026/how-to-get-all-values-from-the-inner-maps-of-a-map-using-a-common -key –

+0

@ShiladittyaChakraborty, aslında, bunun beklenen yolunun neden işe yaramadığını soruyorum. Ayrıca, görev, başvurduğunuz sorudan biraz farklı. – hotkey

cevap

11

ama toplamak istediğiniz istediğiniz aslında girdisinin değeri:

bir Map<B, List<C>>, sen Map.Entry<B,C> C karşılık gelecek bir mapping eklemek için gerekenleri almak için Girişin kendisi değil. Mevcut kodunuzla, bir Map<B, List<Map.Entry<B, C>>> elde edecektiniz. Bu itibarla

, sadece Collectors.mapping bir çağrı eksik. Bu toplayıcı Akış elemanını verilen eşleştirici işleviyle eşleştirecek ve bu sonucu akışaşağı kabına toplayacaktır. Bu durumda, eşleştirici Map.Entry::getValue (bu nedenle, harita girişindeki değeri döndürür) ve alt akış toplayıcısı List'a toplanır.

public <A, B, C> Map<B, List<C>> groupsByInnerKey(Map<A, Map<B, C>> input) { 
    return input.values() 
      .stream() 
      .flatMap(it -> it.entrySet().stream()) 
      .collect(Collectors.groupingBy(
       Map.Entry::getKey, 
       Collectors.mapping(Map.Entry::getValue, Collectors.toList()) 
      )); 
} 
+1

Teşekkürler, işe yaradı. Yani, aslında derleyicinin hata mesajı ile kafam karıştı. Statik olmayan bağlam hakkında değil, tür uyumsuzluğu hakkında söylemeliyim. :) – hotkey

7

Akışınız boru hattı bir Map<B, List<Map.Entry<B,C>>> değil, bir Map<B, List<C>> döndürür. Bir yayın kaynağı Map.Entry nesnelerin oluşmaktadır

return input.entrySet() 
     .stream() 
     .flatMap(it -> it.getValue().entrySet().stream()) 
     .collect(Collectors.groupingBy(Map.Entry::getKey,Collectors.mapping(Map.Entry::getValue,Collectors.toList())));