使用 Java 流迭代两个相同的集合

Iteration of two identical Set using Java Streams

我有两个具有相同类型对象的 HashSet。我的搜索条件是,在第一组中搜索,如果不存在,则在另一组中搜索。我已经按照下面给出的步骤尝试使用 Stream 层

Set<MyObject> firstSet = new HashSet<>();
Set<MyObject> secondSet = new HashSet<>();

这两个集合有一些值。

Predicate<MyObject> match = myObject -> StringUtils.equals(myValue, myObject.getMyValue());

firstSet.values().stream().filter(match).findFirst()
.orElse(secondSet.values().stream().filter(match)
.findFirst().orElseThrow(()-> new MyException()));

我的匹配对象在第一个集合中,我试图手动获取它并且我得到了它...但是使用上面的迭代,即使第一个集合有匹配的对象,我也总是得到异常。请纠正我..谢谢提前。

您的问题是您没有按预期使用 Optional.orElse

当您使用 Optional.orElse 时,它的参数会被 急切地 评估。这意味着首先搜索您的第二组,以解析您第一组的 Optional.orElse.

的参数

相反,使用 Optional.orElseGet,它接收一个 Supplier 被评估 lazily:

firstSet.stream()
    .filter(match)
    .findFirst()
    .orElseGet(() -> secondSet.stream()
        .filter(match)
        .findFirst()
        .orElseThrow(()-> new MyException()));

编辑: 正如 Holger 在评论中所建议的,有一种更简单的方法:

Stream.of(firstSet, secondSet)
    .flatMap(Set::stream)
    .filter(match)
    .findFirst()
    .orElseThrow(MyException::new);

先流式传输集合然后调用 flatMap 可确保第一个集合的元素全部出现在第二个集合的元素之前。