gpt4 book ai didi

java - Java 8 中 throwingMerger 的替代方案

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:21:34 25 4
gpt4 key购买 nike

我正在实现自己的收集器,该收集器使用合并功能。不幸的是,对于我的某些情况,我无法重用以下抛出 IllegalStateException 的 JDK 合并函数。

java.util.stream.Collectors#throwingMerger

发生这种情况是因为它具有 private 访问修饰符并且来自其他(非内部)类的访问受到限制。但是,javadoc 说明如下:

This can be used to enforce the assumption that the elements being collected are distinct

但是,正如我所见,Java 文档已经过时了。它不能被使用。问题是 JDK 是否为 java 开发人员提供了对类似功能的访问(类似的方法、常量等),还是应该自己编写?

最佳答案

throwingMerger()实现如下

private static <T> BinaryOperator<T> throwingMerger() {
return (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); };
}

您可以将类似的方法添加到您的代码库中,但您应该意识到该合并的根本问题:异常消息不正确。该函数的第一个参数是旧值,而不是键。该键对该函数不可用,因此该合并函数不可能生成包含重复键的异常消息。

因此,既然不可能在这个地方解决这个问题,这个函数最好是一个实现细节,所以它可以在没有任何兼容性限制的情况下为 Java 9 删除。

为了提供合理的诊断,不带合并功能的 toMap 需要与带(非抛出)合并功能的 toMap 完全不同的实现,因此 toMaptoConcurrentMap 没有合并功能的收集器已被完全重写。

要求抛出合并功能的一个常见原因是,没有 toMap 重载接受没有合并功能的 map Supplier。但是由于抛出合并不会做正确的事情,并且在应该拒绝重复键时需要一种完全不同的方法,您可以使用 this answer 的收集器。反而。它的一个稍微改进的版本是

public static <T, K, V, M extends Map<K,V>> Collector<T, ?, M> toMap(
Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends V> valueMapper,
Supplier<M> mapSupplier) {

return Collector.of(mapSupplier,
(m,t) -> putUnique(m, keyMapper.apply(t),
Objects.requireNonNull(valueMapper.apply(t))),
(m1,m2) -> {
if(m1.isEmpty()) return m2;
if(!m2.isEmpty()) m2.forEach((k,v) -> putUnique(m1, k, v));
return m1;
});
}
private static <K, V> void putUnique(Map<K, V> map, K key, V v1){
V v2 = map.putIfAbsent(key, v1);
if(v2 != null) throw new IllegalStateException(
String.format("Duplicate key %s (values %s and %s)", key, v1, v2));
}

关于java - Java 8 中 throwingMerger 的替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45201041/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com