2016-11-11 40 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); 
    } 
}