Java8 Stream:满足条件后收集元素

Ash*_*iya 28 java java-8 java-stream

我的POJO如下

class EventUser {
  private id;
  private userId;
  private eventId;
}
Run Code Online (Sandbox Code Playgroud)

我按如下方式检索EventUser对象:

List<EventUser> eventUsers = eventUserRepository.findByUserId(userId);
Run Code Online (Sandbox Code Playgroud)

说'eventUsers'如下:

[
{"id":"id200","userId":"001","eventId":"1010"},
{"id":"id101","userId":"001","eventId":"4212"},
{"id":"id402","userId":"001","eventId":"1221"},
{"id":"id301","userId":"001","eventId":"2423"},
{"id":"id701","userId":"001","eventId":"5423"},
{"id":"id601","userId":"001","eventId":"7423"}
]
Run Code Online (Sandbox Code Playgroud)

使用流式传输,而不使用任何中间变量,如何在给定的EventUser.id之后过滤和收集事件:ex:

List<EventUser> filteredByOffSet = eventUsers.stream.SOMEFILTER_AND_COLLECT("id301");
Run Code Online (Sandbox Code Playgroud)

结果应该是:

[{"id":"id301","userId":"001","eventId":"2423"},
{"id":"id701","userId":"001","eventId":"5423"},
{"id":"id601","userId":"001","eventId":"7423"}]
Run Code Online (Sandbox Code Playgroud)

Pet*_*rey 24

在Java 8中,您需要一个有状态的过滤器

public static <T> Predicate<T> from(Predicate<T> test) {
    boolean[] found = { false };
    // once found, always true
    return t -> found[0] || (found[0] = test.test(t));
}
Run Code Online (Sandbox Code Playgroud)

注意:这仅对单线程流有意义.

List<EventUser> filteredByOffSet = 
     eventUsers.stream()
               .filter(from(e -> "id301".equals(e.getId()))
               .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

  • @PeterLawrey这是一个*非常糟糕的主意,我至少会在这里强制`顺序` (5认同)
  • 我喜欢这个 - 它比[你在这个问题上的答案]简洁得多(/sf/answers/2505387181/) (2认同)
  • @PeterLawrey顺便说一下[dropWhile有java-8的后端口](/sf/answers/1789942661/) (2认同)
  • 这不起作用.lambda中的变量需要是"final"或有效的final.在lambda中无法修改`found`变量.它需要包含在`boolean [1]`或`AtomicBoolean`或类似的东西中. (2认同)

Dmi*_*ets 21

使用Java 9中的" dropWhile ".

  • 请在答案中使用`dropWhile`添加一个示例.现在这是一个仅限链接的答案,有被删除的风险:) (8认同)
  • @AshikaUmangaUmagiliya如果您坚持使用Java8,我建议使用提供dropWhile的StreamEx库(以及其他许多). (4认同)

S.K*_*.K. 14

首先查找搜索项的索引:

int asInt = IntStream.range(0, list.size())
    .filter(userInd-> list.get(userInd).equals(<criteria>))
    .findFirst()
    .getAsInt();
Run Code Online (Sandbox Code Playgroud)

获取索引上和之后的项目:

list.stream().skip(asInt).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)