Java中字符串的大小写不敏感哈希图

时间:2018-11-13 02:06:08

标签: java case superclass

我遇到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}

2 个答案:

答案 0 :(得分:1)

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

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

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

}

测试类需要进行以下修改:

import java.util.*;
import java.io.File;
import java.io.FileNotFoundException;

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

    }
}

答案 1 :(得分:1)

简单修复;

CaseInsensitiveMap stuff = new CaseInsensitiveMap();

打印出来;

{happy=11}
11
{happy=11}

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

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

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