同时扩展HashMap和LinkedHashMap?

4

我想要扩展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 扩展了 HashMap<String, Double> 并添加了上述方法 - 我只是扩展了 HashMap 而不是 LinkedHashMap。这将不允许我在实例化 LinkedHashMap 时访问该方法。
我曾考虑修改原始 HashMap 类的源代码(通过添加 putIfGreaterThan 方法),但是我无法修改源代码,除非反编译整个类(当我尝试这样做时,我会得到很多其他错误,因此我认为仅仅扩展 HashMap 类会更容易,但这样做意味着我不能在 HashMapLinkedHashMap 上使用 putIfGreaterThan 方法)。
此外,如果我将该方法添加到原始类中,任何人都可以在任何 HashMap (即使 map 包含两个字符串)上调用此方法,但是该方法仅适用于包含 String 和 Double 或 String 和 Int 的 HashMap。因此,我认为更有意义的是扩展原始类并使用与 String 和 Double 的 HashMap 相关的方法自定义当前类。
有什么建议吗?
谢谢

2
我建议使用组合。让你的类拥有一个哈希表,然后用你的逻辑包装地图的put方法。 - chatton
修改HashMap类本身的行为,不仅仅是你自己的自定义类,是无法完成的。而这是有充分理由的:这将会为Java应用程序引入安全噩梦。 - VGR
为什么要使用冗余的 if (containsKey(key ) != true),而不是直接使用 if (! containsKey(key)) - Lew Bloch
不要修改核心API。你知道Java禁止多重继承实现(类),只允许多重继承接口,对吗? - Lew Bloch
3个回答

2

让您的自定义地图实现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) 吗? - NAMS
如果我实现Map接口,我就必须添加12个未实现的方法,例如size()、containsKey()和isEmpty()。现在我需要为每个方法添加具体实现。似乎为了定义一个新方法而做了很多额外的工作。 - Kevin Little
@KevinLittle 你只需在继承的方法体中调用包装后的地图的相应方法,就像我在我的答案中为 size() 所做的那样:public boolean isEmpty(){return map.isEmpty()} 等等。 - Calculator
好的,我明白了。我想我会接受这个答案,但是我想知道为什么这种方法比@chatton建议的方法(使用组合)更优越——使用那种策略,我不需要添加未实现的方法。此外,如果我只定义适用于String、Double或String、Int的方法,为什么你建议我使用K、V而不是<String,Double>?谢谢! - Kevin Little
如果你想要一个String, Double的映射,则<String, Double>映射是有意义的 - 我已经做了更改。将给定的映射进行包装就是组合 - 自定义映射具有另一个映射。此外实现Map接口的好处在于,自定义映射不仅拥有一个映射,而且本身也是一个映射。这样,您可以像使用任何其他映射一样使用自定义映射。 - Calculator

0

0

你不能将自己的方法添加到现有的 HashMap 或 LinkedHashMap 类中。 唯一的方法是创建一个自定义类 MyHashMap<K,V>,该类实现了 Map 接口,并在其中放置您的逻辑,并将该类与 HashMap 和/或 LinkedHashMap 组合起来,让您的客户端操作 MyHashMap


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接