2016-08-18 31 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。