2015-10-05 158 views
0

我有一個Java 8的對象流,我想在給定的謂詞匹配後忽略對象。過濾流直到謂詞

例如:我想保留所有字符串 - 「BREAK」(包括它)。

public List<String> values = Arrays.asList("some", "words", "before", "BREAK", "AFTER"); 

@Test 
public void testStopAfter() { 
    Stream<String> stream = values.stream(); 
    //how to filter stream to stop at the first BREAK 
    //stream = stream.filter(s -> "BREAK".equals(s)); 
    final List<String> actual = stream.collect(Collectors.toList()); 

    final List<String> expected = Arrays.asList("some", "words", "before", "BREAK"); 
    assertEquals(expected, actual); 
} 

由於它是失敗(預期:< [一些,也就是說,之前,BREAK]>但:< [一些,也就是說,之前,BREAK,AFTER]>),如果我去掉過濾器,我只得到「BREAK」

我在想一個有狀態的謂詞(請參閱下面的答案),但如果有更好的解決方案,我會遊蕩嗎?

+0

子流或類似的東西? – awksp

+0

看起來你想從原始流中獲得一個子流。 –

+0

@LuiggiMendoza是一個子流將是非常好的 –

回答

0

使用一個statefull Predicate在給定Predicate匹配之前回答true和false。

[...] 
stream = stream.filter(makeUntil(s -> "BREAK".equals(s))); 
[...] 


public static <T> Predicate<T> makeUntil(final Predicate<T> predicate) { 
    return new Predicate<T>() { 

     private boolean hasMatched; 

     @Override 
     public boolean test(final T s) { 
      if (hasMatched) { 
       return false; 
      } 
      else { 
       hasMatched = predicate.test(s); 
       return true; 
      } 
     } 

    }; 
} 
+2

小心。這假定'流'是連續的,每次都不是這樣。 –

+0

@LuiggiMendoza很好的一點。任何想法如何檢查? –

+0

您可以通過調用'Stream#sequential'來確保數據流是順序的,以防萬一您接收到流作爲參數,否則您使用這種方法很好*。 –