【问题标题】:Case insensitive hashmap for strings in javajava中字符串的大小写不敏感哈希图
【发布时间】:2019-04-15 19:09:01
【问题描述】:

我遇到了this post 的不区分大小写的哈希图,并尝试实现它,但我没有得到预期的结果。出于某种原因,当我使用不同的大小写并返回 null 时,它没有返回值,我认为在这种情况下你并不真的需要非默认构造函数,但我不确定。

public class CaseInsensitiveMap extends HashMap<String, Integer> {

    @Override
    public Integer put(String key, Integer value) {
       return super.put(key.toLowerCase(), value);
    }

    // not @Override because that would require the key parameter to be of type Object
    public Integer get(String key) {
       return super.get(key.toLowerCase());
    }
}

并像这样使用;

HashMap<String, Integer> stuff = new CaseInsensitiveMap();
stuff.put("happy", 11);
System.out.println(stuff);
Integer result = stuff.get("HAPPy");
System.out.println(result);
System.out.println(stuff);

但结果是;

{happy=11}
null
{happy=11}

【问题讨论】:

标签: java case superclass


【解决方案1】:

由于String被标记为final,可以考虑扩展CharSequence

public class CaseInsensitiveMap<K extends CharSequence, V> implements Map<K, V> {

    private Map<K, V> map = new HashMap<K, V>();

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

    @Override
    public boolean isEmpty() {
        return map.isEmpty();
    }

    @Override
    public boolean containsKey(Object key) {
        return map.containsKey(key.toString().toLowerCase());
    }

    @Override
    public boolean containsValue(Object value) {
        return map.containsValue(value);
    }

    @Override
    public V get(Object key) {
        return map.get(key.toString().toLowerCase());
    }

    @Override
    public V put(K key, V value) {
        return map.put((K) key.toString().toLowerCase(), value);
    }

    @Override
    public V remove(Object key) {
        return map.remove(key.toString().toLowerCase());
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> m) {
        map.putAll(m);      
    }

    @Override
    public void clear() {
        map.clear();
    }

    @Override
    public Set<K> keySet() {
        return map.keySet();
    }

    @Override
    public Collection<V> values() {
        return map.values();
    }

    @Override
    public Set<java.util.Map.Entry<K, V> > entrySet() {
        return map.entrySet();
    }

    @Override
    public String toString() {
        return map.toString();
    }

}

需要修改的测试类如下:

public class Tester {

    public static void main(String[] args) {

        Map<String, Integer> stuff = new CaseInsensitiveMap<String, Integer>();

        stuff.put("happy", 11);
        System.out.println(stuff);
        Integer result = stuff.get("HAPPy");
        System.out.println(result);
        System.out.println(stuff);

    }
}

【讨论】:

    【解决方案2】:

    简单修复;

    CaseInsensitiveMap stuff = new CaseInsensitiveMap();
    

    打印出来;

    {happy=11}
    11
    {happy=11}
    

    CaseInsensitiveMap 扩展了HashMap&lt;String, Integer&gt;,因此它是它的子类,您将stuff 引用为HashMap(作为超类)这一事实允许它使用默认的get 方法。您甚至可以在 IDE 中看到您在 CaseInsensitiveMap 中的自定义 get(String) 甚至没有被使用。

    如果您对子类使用超类引用,则只会使用被覆盖的方法,就像您在代码中所做的那样。这就是为什么只有您的自定义 put(String, Integer) 方法有效,因为它覆盖了 super 中的方法。

    Referencing Subclass objects with Subclass vs Superclass reference 了解有关该问题的更多信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-26
      • 2011-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-31
      • 2019-06-25
      相关资源
      最近更新 更多