簡體   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