java 中字符串的不区分大小写的哈希图

Case insensitive hashmap for strings in java

我发现 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}

由于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();
    }

}

测试class需要修改如下:

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);

    }
}

简单修复;

CaseInsensitiveMap stuff = new CaseInsensitiveMap();

打印出来;

{happy=11}
11
{happy=11}

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

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

中的方法

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