如果我有List
个包含
new MyObj("some"),
new MyObj("foo"),
new MyObj("bar"),
new MyObj("xyz");
并希望在匹配后使用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;
}
}
Limit a stream by a predicate不重复,因为 包含匹配的元素。但是,我应该能够适应takeWhile操作。
答案 0 :(得分:5)
不幸的是,Stream API并不直接支持这种情况。甚至takeWhile
,这是Java 9中新出现的方法也无法解决这个问题。一些免费的第三方Stream API扩展程序具有您需要的方法。例如,limitWhileClosed中的jOOλ或takeWhileInclusive中的StreamEx(我写的库)。这是一个例子,如何通过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());