Java 8流;在条件下过滤收集

时间:2017-02-14 08:37:45

标签: java java-8 java-stream

如果我有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操作。

1 个答案:

答案 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());