2016-04-06 23 views
2

Akışları kullanarak bir listeyi diğerine eşlemeye çalışıyorum. Orijinal listenin bazı öğeleri eşlenememektedir. Yani, haritalama işlevi uygun yeni bir değer bulamayabilir.Java8 akış haritası - tüm harita işlemlerinin başarılı olup olmadığını kontrol edin.

Eşleştirmelerden herhangi birinin başarısız olup olmadığını bilmek istiyorum. İdeal olarak, bir arıza meydana geldiğinde işlemeyi durdurmak isterim.

Ne anda yapıyorum geçerli:

  • hiçbir eşlenen değeri
  • var ben filter()
  • Sonra dere
  • I collect() gelen boş değerlere kaldırmak ve eğer eşleme fonksiyonu null döndürür Sonucun boyutunu orijinal listenin boyutlarıyla karşılaştırır. Örneğin

:

List<String> func(List<String> old, Map<String, String> oldToNew) 
{ 
    List<String> holger = old.stream() 
          .map(oldToNew::get) 
          .filter(Objects::nonNull) 
          .collect(Collectors.toList); 

    if (holger.size() < old.size()) { 
     // ... appropriate error handling code ... 
    } 
    else { 
     return holger; 
    } 
} 

Bu çok şık değil. Ayrıca, her şey başarısız olduğunda bile her şey işlenir.

Bunu yapmanın daha iyi bir yolu için öneriler? Ya da akıntıları tamamen terk etmeliyim ve eski eski döngüler kullanmalıyım?

+1

Neden null değerine sahipse, eski & null :: get' öğesinden denetlenmeyen bir istisnayı atıp dışarıda yakalamıyorsunuz? – Tunaki

+0

@Tunaki Teşekkürler, bu bir seçenek. Bunun zerafeti veya performansı geliştirip geliştirmeyeceğini bilmiyorum (istisnalar pahalı olduğu için). – daphshez

+0

"Yeni" değişkeninizi adlandırmayın. Bu işe yaramaz ... Ve demek istediği "void List " bir dönüş türü nedir? – Holger

cevap

0

Sen Objects::requireNonNull için filtreyi değiştirmek ve bu ağır kullanım durumuna bağlı olduğundan hiçbir iyi çözüm yoktur akımına

+3

"NullPointerException" ı yakalamak iyi bir fikir değildir. Bunu tavsiye etmem. – Tunaki

1

dışında bir NullPointerException yakalayabiliriz. Örneğin. arama hatalarının beklenmedik olması veya hata işlemenin bir istisna oluşturmasına neden olması bekleniyorsa, eşleştirme işlevindeki ilk başarısız aramaya bir istisna atmak gerçekten iyi bir seçim olabilir. Ardından, takip kodu hata koşullarına dikkat etmemelidir.

bu olabilir işleme başka yolu:

List<String> func(List<String> old, Map<String, String> oldToNew) { 
    Map<Boolean,List<String>> map=old.stream() 
     .map(oldToNew::get) 
     .collect(Collectors.partitioningBy(Objects::nonNull)); 
    List<String> failed=map.get(false); 
    if(!failed.isEmpty()) 
     throw new IllegalStateException(failed.size()+" lookups failed"); 
    return map.get(true); 
} 

o başarısızlıklar için null değerleri içeren bir çoğunlukla anlamsız liste toplar gibi bu hala kabul başarılı durum için optimize edilen edilebilir. Ancak, başarısızlık sayısını söyleyebilmenin bir noktası vardır (bir harita işlevinin kullanılmasından farklı olarak). detaylı hata analizi yüksek öncelik varsa

, böyle bir çözüm kullanabilir:

List<String> func(List<String> old, Map<String, String> oldToNew) { 
    Map<Boolean,List<String>> map=old.stream() 
     .map(s -> new AbstractMap.SimpleImmutableEntry<>(s, oldToNew.get(s))) 
     .collect(Collectors.partitioningBy(e -> e.getValue()!=null, 
      Collectors.mapping(e -> Optional.ofNullable(e.getValue()).orElse(e.getKey()), 
       Collectors.toList()))); 
    List<String> failed=map.get(false); 
    if(!failed.isEmpty()) 
     throw new IllegalStateException("The following key(s) failed: "+failed); 
    return map.get(true); 
} 

Bu başarısız aramalar için başarısız anahtarları ve başarıyla eşlenen değerlerin listesini içeren iki anlamlı listeleri toplar. Her iki listenin de iade edilebileceğini unutmayın.