2016-03-31 61 views
0

ile filtreledikten sonra topladım, bir DTO listesi var, bu dtos etiketlerin bir listesini içerir. Her biri kendi anahtarına ve değerine sahip 2 etiket içeren dtos bulmak için arıyorum. Bu kod çalışacak - ama sadece iç filtrelere ilk bulacağını iBir akışı Java 8

List<myDTO> responsesList = getAllData(parameters); 
List<myDTO> result = responsesList.stream() 
        .filter(d -> 
          d.getData().getTags().stream() 
           .filter(t -> t.getKey().equals(key1) && t.getValue().equals(value1)) 
           .findFirst().isPresent()) 
        .filter(d -> 
          d.getData().getTags().stream() 
           .filter(t -> t.getKey().equals(key2) && t.getValue().equals(value2)) 
           .findFirst().isPresent()) 
        .collect(Collectors.toList()); 

ben ne eksik olduğunu kriterlere birden fazla nesne var olduğu durumda, yerine birinci bulma toplamak istiyoruz findFirst().isPresent() yerine bir koleksiyon topla? Collect(collectors.toList) yaparsam "Çıkarım değişkeni T uyumsuz sınırlar" gibi bir hata mesajı alıyorum?

+0

'findFirst' sadece etiketleri değil, gerçek DTO nesnelere uygulanır. –

+0

Sorunuzdaki kodun, derleyici hatası oluşturan asıl kod olduğundan emin misiniz? list.stream(). filter (…) .filter (…) .collect (Collectors.toList()) hemen hemen orijinal List ile aynı türde bir Listeyi geri göndermelidir. Filtre'ye iletilen gerçek Tahminler bunu değiştirmeyecektir. – VGR

+0

Bence senin kodun iyi. DTO'ları filtreliyorsunuz * etiketleri * filtreliyor * ve bu etiket filtresi 'key1 = value1 'ile eşleşen en az bir etiket olduğunu görüyor. Bunun neden bir sorun olduğunu düşündüğünüz konusunda daha spesifik olabilir misiniz? – dcsohl

cevap

1

Aslında ne istediğinizi net değil. Hem key1/value1 etiketine hem de key2/value2 etiketine sahip tüm myDTO nesnelerini toplamanız gerekiyorsa, kodunuz zaten çalışır. Aslında istiyorsanız

List<myDTO> result = responsesList.stream() 
       .filter(d -> 
         d.getData().getTags().stream() 
          .anyMatch(t -> t.getKey().equals(key1) && t.getValue().equals(value1)) 
         && 
         d.getData().getTags().stream() 
          .anyMatch(t -> t.getKey().equals(key2) && t.getValue().equals(value2))) 
       .collect(Collectors.toList()); 

:

List<myDTO> result = responsesList.stream() 
       .filter(d -> 
         d.getData().getTags().stream() 
          .anyMatch(t -> t.getKey().equals(key1) && t.getValue().equals(value1))) 
       .filter(d -> 
         d.getData().getTags().stream() 
          .anyMatch(t -> t.getKey().equals(key2) && t.getValue().equals(value2))) 
       .collect(Collectors.toList()); 

Ayrıca tek yüklem içine hem filters katılabilir bu zevk meselesi olsa,: filter(predicate).findFirst().isPresent()anyMatch(predicate) ile değiştirilmesi mümkündür olarak Sadece bunu kısaltabilir etiketler eşleşen toplamak, bir flatMap gerekebilir:

List<myTag> result = responsesList.stream() 
       .flatMap(d -> d.getData().getTags().stream()) 
       .filter(t -> t.getKey().equals(key1) && t.getValue().equals(value1) || 
          t.getKey().equals(key2) && t.getValue().equals(value2)) 
       .collect(Collectors.toList());