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