2016-11-11 69 views
1

看到这个代码: (这是工作的代码,但我不喜欢用2线所以找我怎样才能使它更好)Java的8个流 - 或条件

ItemDetails[] items = response.getDetailsList(); 
items = Arrays.stream(items).filter(x -> !x.getName().equalsIgnoreCase("acl1")).toArray(ItemDetails[]::new); 
items = Arrays.stream(items).filter(x -> !x.getName().equalsIgnoreCase("acl2")).toArray(ItemDetails[]::new); 

我想不出如何使用filter中的OR (|)条件从List中删除两个特定元素,因为它会给我编译时间错误(在IDE中),最后我会用上面的两个filters。 我可能会错过什么?

这是我尝试使用或

items = Arrays.stream(items).filter(x -> !x.getName().equalsIgnoreCase("acl1") || 
     x -> !x.getName().equalsIgnoreCase("acl2")).toArray(ItemDetails[]::new); 

=>的IntelliJ会抱怨这一个(上图)

items = Arrays.stream(items).filter(x -> !x.getName().equalsIgnoreCase("acl1"") || 
     x.getName().equalsIgnoreCase("acl2")).toArray(ItemDetails[]::new); 

在运行时不工作(不过滤)

带有注释的代码(我试过)的完整的代码供参考

public static void mapTest() { 

     AclDetailItem[] items = new AclDetailItem[3]; 

     AclDetailItem item1 = new AclDetailItem(); 
     item1.setAclName("acl1"); 

     AclDetailItem item2 = new AclDetailItem(); 
     item2.setAclName("acl2"); 

     AclDetailItem item3 = new AclDetailItem(); 
     item3.setAclName("acl3"); 

     items[0] = item1; 
     items[1] = item2; 
     items[2] = item3; 

     System.out.println ("Before " + items.length); 


     items = Arrays.stream(items).filter(x -> !x.getAclName().equalsIgnoreCase("acl1")).toArray(ItemDetails[]::new); 
     items = Arrays.stream(items).filter(x -> !x.getAclName().equalsIgnoreCase("acl2")).toArray(ItemDetails[]::new); 

     System.out.println ("After " + items.length); 
    } 
+0

什么错误?你尝试了什么?这很重要。 – Carcigenicate

+0

我没有downvote,但这是一个很差的问题。 – Carcigenicate

+0

items = Arrays.stream(items).filter(x - >!x.getName()。equalsIgnoreCase(“redirect”)|| x - >!x.getName()。equalsIgnoreCase(“success”))。toArray( ItemDetails [] ::新); – Rockoder

回答

0
items = Arrays.stream(items).filter(
    x -> !x.getName().equalsIgnoreCase("redirect") 
    || x->!x.getName().equalsIgnoreCase("success")) 
    .toArray(ItemDetails[]::new); 

请注意第二个x->。这用于在lambda开始时绑定一个变量。把它放在中间是无效的,因为x已经存在于范围内,所以不必要。只要删除该位:

items = Arrays.stream(items).filter(x -> 
    !x.getName().equalsIgnoreCase("redirect") 
    || !x.getName().equalsIgnoreCase("success")) 
    .toArray(ItemDetails[]::new); 
+0

将测试此答案并更新。我想我已经尝试了所有可能的排列方式,但没有奏效。我尝试了很多变化,最后放弃使用我发布的解决方案,因为我想转移到下一个任务。 – Rockoder

+0

更新:我的坏,我搞砸了语法。现在它编译好了。测试它。 – Rockoder

+0

如果这个问题是有效的,请注意让家伙们!它搞砸了我的徽章/排名 – Rockoder

5

第一个是不正确的,因为它有一个x ->太多。 第二个不会按照您构建始终为true的条件进行过滤。只需在filter-方法中细化条件,它就会过滤。

编辑(作为问题得到详细): 我仍然认为,你有一个错误在你的情况。您可能想排除acl1acl2。如果是这样,你的情况应该相当看起来类似:

!(x.getAclName().equalsIgnoreCase("acl1") || x.getAclName().equalsIgnoreCase("acl2")) 
// or if you prefer && 
!x.getAclName().equalsIgnoreCase("acl1") && !x.getAclName().equalsIgnoreCase("acl2") 
// or if you prefer regular expressions/matches 
!x.getAclName().matches("(?i)^acl[1|2]$") 
+0

谢谢!这工作完美。有人可以upvote我的问题,如果这可以帮助别人!当它吸引人们的有效评论时,不知道它为什么是-1。 – Rockoder

0

你应该为每个条件创建多个谓词以及使用或加入。我已经添加了以下示例:

public class MeTest { 

    Predicate<Integer> con1 = i -> i==0; 
    Predicate<Integer> con2 = i -> i==1; 
    Predicate<Integer> con3 = i -> i==2; 

    @Test 
    public void testOr() { 
     List<Integer> asdas = IntStream.range(1, 10).boxed().filter(con1.or(con2).or(con3)).collect(toList()); 
     System.out.println("asdas = " + asdas); 
    } 
}