2017-02-14 69 views
3

如果我有一個像Java 8流;過濾器收集的條件

new MyObj("some"), 
new MyObj("foo"), 
new MyObj("bar"), 
new MyObj("xyz"); 

一個包含對象List,並希望與Java 8對其進行過濾匹配一些條件後流,說

myObj.prop = "foo"; 

怎麼會是這樣實現的?

上述例子的結果應該是

new MyObj("some"), 
new MyObj("foo") 

這將是「傳統」的方式:

List<MyObj> results = new ArrayList<>(); 
for (MyObj myObj : myObjList) { 
    if (!myObj.prop.equals("foo")) { 
    results.add(myObj); 
    } else { 
    results.add(myObj); 
    break; 
    } 
} 

這不是exaclty的Limit a stream by a predicate重複,因爲這不包括匹配的元素。但是,我應該能夠適應takeWhile操作。

+3

@AndyTurner他要返回的所有元素,直到滿足該條件 – nbokmans

+0

似乎類似於http://stackoverflow.com/ question/23308193/break-or-return-from-java-8-stream-foreach –

回答

3

不幸的是,這種情況並不直接受Stream API支持。即使是在Java 9中新出現的方法takeWhile也不能解決這個問題。一些免費的第三方流API擴展有一個你需要的方法。例如,limitWhileClosedjOOλtakeWhileInclusiveStreamEx(我寫的圖書館)。下面是一個例子,如何通過StreamEx完成:

List<MyObj> results = StreamEx.of(myObjList) 
    .takeWhileInclusive(myObj -> !myObj.prop.equals("foo")).toList(); 

jOOλ版本看起來很相似。

不使用第三方庫,你可以在兩個通道解決這個問題:

int idx = IntStream.range(0, myObjList.size()) 
     .filter(i -> myObjList.get(i).prop.equals("foo")) 
     .findFirst().orElse(myObjList.size()); 

List<MyObj> results = myObjList.stream().limit(idx+1).collect(Collectors.toList()); 
+2

...或者'results = idx == myObjList.size()? myObjList:myObjList.subList(0,idx + 1);',這取決於用例。 – Holger