2017-02-14 66 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