Java8流:在满足条件后收集元素

Java8流:在满足条件后收集元素,java,java-8,java-stream,Java,Java 8,Java Stream,我的建议如下 class EventUser { private id; private userId; private eventId; } 我检索EventUser对象,如下所示: List<EventUser> eventUsers = eventUserRepository.findByUserId(userId); [ {"id":"id200","userId":"001","eventId":"1010"}, {"id":"id101","userId"

我的建议如下

class EventUser {
  private id;
  private userId;
  private eventId;
}
我检索EventUser对象,如下所示:

List<EventUser> eventUsers = eventUserRepository.findByUserId(userId);
[
{"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"}
]
使用流式处理,并且不使用任何中间变量,如何在给定EventUser.id之后过滤和收集事件: 例:


使用Java 9中的“”。

首先查找搜索项的索引:

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

如果不使用任何中间变量,就无法做到这一点。找到位置并迭代到最后(请参见下面的问题,以便更准确地回答)

在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));
}
来自的公共静态谓词(谓词测试){
发现布尔[]={false};
//一旦发现,永远是真的
返回t->found[0]|(found[0]=test.test(t));
}
注意:这仅适用于单线程流

List<EventUser> filteredByOffSet = 
     eventUsers.stream()
               .filter(from(e -> "id301".equals(e.getId()))
               .collect(Collectors.toList());
List filteredByOffSet=
eventUsers.stream()
.filter(从(e->“id301”.equals(e.getId()))
.collect(Collectors.toList());

@ernest_k生成的集合应该在“id301”之后(而不是之前)有元素。输入列表(以及由此产生的初始流)是否总是按
eventId
排序(示例留下了这样的印象)?@JanusVarmarken未按eventId排序..可能重复我喜欢这个-它比@PeterLawrey更简洁是的,我更喜欢这个!-@PeterLawrey这真是个坏主意,我至少会强制
顺序
here@PeterLawrey顺便说一句,这不能像写的那样工作。lambda中的变量必须是
final
或有效的f最后。无法在lambda中修改
found
变量。它需要用
布尔值[1]包装
原子布尔
或类似。@Ashikaumagaumagiliya thx致全能Holger这在java-8中也是可能的。请尝试将其链接到您的答案,这应该是IMO认可的答案。请在您的答案中添加一个使用
dropWhile
的示例。现在这是一个仅链接的答案,有被删除的风险:)在使用此方法时,应考虑添加流。如果它是无序的,那么行为是不确定的。@ashikaumagaumagiliya如果你坚持使用Java8,我建议使用提供dropWhile的StreamEx库(以及许多其他库)。这应该是公认的答案,尽管我会使用
List.subList(from,to)
而不是skip@FedericoPeraltaSchaffner既然可以跳过,为什么还要创建子列表?@TimB subList不会创建新列表,它只是一个原始列表范围的视图list@FedericoPeraltaSchaffner视图是一个对象。我同意这不像复制列表那样费力,它仍然大于零。@TimB也许我不够清楚。我的意思是子列表而不是流,跳过并收集到一个新列表
list.stream().skip(asInt).collect(Collectors.toList());
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));
}
List<EventUser> filteredByOffSet = 
     eventUsers.stream()
               .filter(from(e -> "id301".equals(e.getId()))
               .collect(Collectors.toList());