【问题标题】:Extend HashMap and LinkedHashMap at the Same Time?同时扩展HashMap和LinkedHashMap?
【发布时间】:2017-03-10 18:21:50
【问题描述】:

我想扩展HashMap 以添加方法putIfGreaterThan,它基本上检索给定键的值,如果新值大于旧值,我们用新值更新旧值。像这样:

  public void putIfGreaterThan(String key, Double value )
  {

  if (containsKey(key ) != true) {
  put( key , value );
  } else {
  if (get(key ) < value) {
  System. out .println("Adding new value: " + value + " to map" );
  put( key , value );
  } else {
  System. out .println("Did not add value: " + value + " to map" );
  }
  }


  }

上面的程序运行良好 - 但是我想将此方法添加到 HashMapLinkedHashMap。换句话说,如果有人实例化:

HashMap hashmap = new HashMap();

他们应该能够访问该方法:

hashmap.putIfGreaterThan();

如果有人实例化:

LinkedHashMap linkedhashmap = new LinkedHashMap();

他们应该能够访问该方法:

linkedhashmap .putIfGreaterThan();

如果我创建一个新类如下:

MyHashMap extends HashMap&lt;String, Double&gt; 并添加前面提到的方法 - 我只是扩展 HashMap 而不是 LinkedHashMap。如果我实例化 LinkedHashMap,这将不允许我访问该方法。

我正在考虑修改原始 HashMap 类中的源代码(通过添加方法 putIfGreaterThan)但是我无法修改源代码,除非我反编译整个类(当我尝试这样做时,我得到一堆其他错误,所以我认为扩展HashMap 类会更容易,但这样做意味着我不能在HashMapLinkedHashMap 上使用putIfGreaterThan 方法。

此外,如果我将该方法添加到原始类中,则可以在任何 HashMap 上调用此方法(即使映射包含两个字符串),但该方法仅适用于包含字符串的 HashMap 和Double 或 String 和 Int。因此,我认为扩展原始类并使用与 String 和 Double 的 HashMap 相关的方法自定义当前类更有意义。

有什么建议吗?

谢谢

【问题讨论】:

  • 我建议使用合成。让你的类有一个 hashmap,然后用你的逻辑包装 map 的 put 方法。
  • 不能修改 HashMap 类本身的行为,而不仅仅是您自己的自定义类,这是有充分理由的:它会给所有地方的 Java 应用程序带来安全噩梦。
  • 为什么是多余的if (containsKey(key ) != true) 而不是简单的if (! containsKey(key))
  • 不要修改核心 API。您知道 Java 禁止实现(类)的多重继承,而只允许接口的多重继承,对吧?

标签: java inheritance interface hashmap


【解决方案1】:

让您的自定义地图实现Map 接口,并用它包装一个由类用户通过构造函数提供的具体地图:

public class MyMap implements Map<String, Double>{
    private final Map<String, Double> map;  

    public MyMap(Map<String, Double> map){
        this.map = map;
    }

    public void putIfGreaterThan(String key, Double value ){...}

    @Override
    public int size() {
        return map.size();
    }

    //inherited methods
}

这个类可以这样使用:

MyMap map = new MyMap(new LinkedHashMap<>());

或:

MyMap map = new MyMap(new HashMap<>());

【讨论】:

  • 你不应该在这里使用putIfGreaterThan(K key, V value)吗?
  • 如果我实现了 Map 接口,我不得不添加 12 个未实现的方法,例如 size()、containsKey() 和 isEmpty()。我现在需要将正文添加到每个方法中。似乎只是为了定义 1 个新方法需要做很多额外的工作..
  • @KevinLittle 您只需要像我在我的回答中为size() 所做的那样,在继承方法的主体中调用包装映射的相应方法:public boolean isEmpty(){return map.isEmpty()} 等等
  • OK 是有道理的。我想我会接受这个答案,但是我想知道为什么这种方法比@chatton 建议的方法更好(使用组合)-我不需要使用该策略添加未实现的方法。还有你为什么建议我在 上使用 K、V(如果我只定义适用于 String、Double 或 String、Int 的方法)谢谢!
  • @KevinLittle 如果你想要一个字符串,Double map &lt;String, Double&gt; 是有意义的——我改变了它。包装给定地图是组合 - 自定义地图有另一个地图。额外实现 Map 接口的好处是自定义地图不仅有地图,而且本身就是地图。这样您就可以像使用任何其他地图一样使用自定义地图。
【解决方案2】:

Java 不支持多继承,但您可以使用接口来完成。

Java Multiple Inheritance

【讨论】:

    【解决方案3】:

    您不能将您的方法添加到现有的 HashMap 或 LinkedHashMap 类。 唯一的方法是创建一个自定义类MyHashMap&lt;K,V&gt;,它实现Map 接口并将您的逻辑放在那里并使用HashMap 和(或)LinkedHashMap 组成该类,并让您的客户在MyHashMap 上运行。

    【讨论】:

      猜你喜欢
      • 2012-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-02
      • 2013-11-29
      • 2011-02-22
      • 2011-01-25
      • 1970-01-01
      相关资源
      最近更新 更多