如何检查 Java 流中映射结果的子值是否相同?

How to check if sub values of a mapped results are the same in Java stream?

我有以下流转换:

Stream.of(string1, string2)
  .map(this::function1) // generate Stream<Pair<Integer, Integer>>

如何检查配对的密钥是否相同?因为在进行下一步之前我需要确保它们是相同的。

您想在同一个调用中抛出异常,那么这是在单个调用中的另一种方式:

Stream.of(string1, string2).map(this::function1).reduce((p, q) -> {
        if (p.getKey().compareTo(q.getKey())==0)
            return p;
        else
            return null;
    }).orElseThrow(() -> new Exception("keys don't match"));

请注意,如果值匹配,您将前往 return Optional<Pair<Integer, Integer>>

好吧,要求看起来像 this question, and Stuart Marks added an implementation 中的要求,即根据对象的不同属性过滤流。

这是他的代码:

public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
    Set<Object> seen = ConcurrentHashMap.newKeySet();
    return t -> seen.add(keyExtractor.apply(t));
}

但是,我们不是在寻找过滤不同的值,而是在寻找相反的东西——特定 属性 的对象与所有其他对象相同

我修改了代码,因此如果其中一个对象的指定 属性 与其他对象不同,它会抛出异常:

static <T> Predicate<T> sameKeyOrThrow(Function<? super T, ?> keyExtractor, Supplier<RuntimeException> exceptionSupplier) {
    Set<Object> seen = ConcurrentHashMap.newKeySet();
    return t -> {
        seen.add(keyExtractor.apply(t));
        if (seen.size() > 1) {
            throw exceptionSupplier.get();
        }
        return true;
    };
}

用法:

Stream.of(string1, string2)
    .map(this::function1)
    .filter(sameKeyOrThrow(pair -> pair.left(), YourRuntimeException::new))

与使用 Collectors::groupingBy 进行收集相比,此方法的优势在于它不会具体化整个流,而是 fails-fast 如果找到不同的值。