2016-08-18 116 views
3

我有以下片段收集具有包含特定過濾器filterNamename字符串屬性的特定對象。Java 8流nonNull在對象的屬性

List<Foo> filteredFoo= fooList.stream() 
       .filter(Objects::nonNull) 
       .filter(myFoo -> { 
          if (Strings.isNullOrEmpty(myFoo.getName())) 
           return false; 
          return myFoo.getName().contains(filterName); 
         } 
       ).collect(Collectors.toList()); 

它按預期工作,但我不知道是否有寫if-statement以功能性的方式並以更好的方式檢查空或空的屬性,不必在過濾條件塊一個更優雅的方式。

+2

我很困惑。你已經決定'Objects :: nonNull'需要成爲一個單獨的過濾器,但其他的一切都需要在一個單獨的過濾器中。爲什麼? – zeroflagL

+0

@zeroflagL它是爲了可讀性目的而完成的,對象:nonNull在第二個過濾器作用於對象本身屬性的對象級別上工作。我不知道這是否對性能有影響,但爲了可讀性,我認爲這很有用。 –

+0

這就是我的觀點:如果你爲可讀性而努力,那麼爲什麼你有一個複雜的第二個過濾器,而不是單獨的,也許是可重用的過濾器,比如'Foo :: hasName',例如? – zeroflagL

回答

7

與以下替換第二filter

.filter(myFoo -> Optional.ofNullable(myFoo.getName()) 
         .filter(n -> n.contains(filterName)) 
         .isPresent()) 

甚至:

.filter(myFoo -> { 
    String name = myFoo.getName(); 
    return name != null && name.contains(filterName) 
}) 
+0

在你的第一個例子中'!Strings.isNullOrEmpty(n)'是毫無意義的。 – zeroflagL

+0

@zero你能解釋一下嗎? 'name'可以是'null'或空的。可選僅解決第一種情況。 –

+4

無論是否爲空都沒關係。一個空字符串不包含'filterName',並且無論如何都要檢查。 '!n.isEmpty()'會更簡潔。 – zeroflagL

0

如果有權訪問Foo類然後移動如果條件的方法isSameName,並使用過濾器如下面

filter(myFoo -> {return myFoo.isSameName(filterName);}) 
1

轉到功能樣式,爲結果表示N:

.filter(foo -> foo.getName() != null && foo.getName().contains(filterName)) 

分裂不會帶來更多的簡單:

.filter(foo -> foo.getName() != null) 
.filter(foo -> foo.getName().contains(filterName)) 

使用謂詞上的Foo ::的getName(對象::參考isNull)是毫無意義的太複雜,只是爲了騰出一個變量。

如果filterName本身不是空的,則不需要Strings.isEmptyOrNull。