繁体   English   中英

类型安全合并 Map 与多种类型的值; `不兼容的类型 java.lang.Object 无法转换为捕获 #1 的 ?`

[英]Type safe merging of Map with multiple types for its value; `incompatible types java.lang.Object cannot be converted to capture#1 of ?`

我有一个容器类,它有一个Map ,它携带多种类型的值。 为了从外部的角度来看是类型安全的,键本身有一个泛型类型,指示值的类型。

键提供了一些基本的工具来查找项目并合并它们的值。 (找到的值类型可能有不同的合并规则)。

public abstract class Key<T> {
  @SuppressWarnings("unchecked")
  T get(Map<Key<?>, Object> data) {
      return (T) data.get(this);
  }

  /** 
    * This must be provided by the implementation. 
    *
    * @param old the old value
    * @param new the new value
    * @returns the merged value
    */ 
  abstract T merge(T old, T new);  
}

Container类看起来像这样。

public class Container {

  private final Map<Key<?>, Object> data = new HashMap<>();

  public <T> Optional<T> get(Key<T> key) {
    return Optional.ofNullable(key.get(data));
  }

  public <T> Container set(Key<T> key, T value) {
    data.put(key, value);
    return this;
  }

  @SuppressWarnings("unchecked")
  public <T> Container merge(Key<T> key, T newValue) {
    data.compute(key, (k, oldValue) -> key.merge((T) oldValue, newValue));
    return this;
  }


  public Container mergeAll(Container that) {
    //this does not compile: incompatible types java.lang.Object cannot be converted to capture#1 of ?
    that.data.forEach((key, value) -> this.data.merge(key, value, key::merge));
    return this;
  }
}

除了最后一个mergeAll方法之外,所有这些都可以正常工作。 它正在查看that容器的所有键并将它们的值与this容器的值合并。

但是, key::merge无法编译并出现错误incompatible types java.lang.Object cannot be converted to capture#1 of ? .

在单个merge()方法中,我通过将类型转换为(T)来解决它。 但在这种情况下,我没有泛型类型,它是? ,但我不能做这样的事情: (key, oldValue) -> key.merge((?) oldValue, (?) value)因为你不能转换为(?)

有没有解决的办法? 或者更好的模式来实现我想要实现的目标?

您应该能够通过编写以下内容来解决此问题:

public Container mergeAll(Container that) {
  that.data.forEach((key, value) -> this.data.merge(key, value, ((Key<Object>) key)::merge));
  return this;
}

在您的示例中, key具有无界通配符类型Key<?> ,因此接受泛型参数的方法只能接受null 由于传递给merge的值属于Object类型,因此您可以将keyKey<Object>

如果这适用于您的情况,另一种解决方案可能是将Key<?>更改为Key<Object>

我认为它不会比这更安全,因为映射Map<Key<?>, Object> data没有提示编译器该值的类实际上应该是钥匙。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM