How do I access nested HashMaps in Java?

2020-01-28 05:12发布

I have a HashMap in Java, the contents of which (as you all probably know) can be accessed by

HashMap.get("keyname");

If a have a HashMap inside another HashMap i.e. a nested HashMap, how would i access the contents? Can i do this like this, inline:

HashMap.get("keyname").get("nestedkeyname");

Thank you.

标签: java hashmap
10条回答
对你真心纯属浪费
2楼-- · 2020-01-28 05:36

As others have said you can do this but you should define the map with generics like so:

Map<String, Map<String, String>> map = new HashMap<String, Map<String,String>>();

However, if you just blindly run the following:

map.get("keyname").get("nestedkeyname");

you will get a null pointer exception whenever keyname is not in the map and your program will crash. You really should add the following check:

String valueFromMap = null;
if(map.containsKey("keyname")){
  valueFromMap = map.get("keyname").get("nestedkeyname");
}
查看更多
欢心
3楼-- · 2020-01-28 05:41

I came to this StackOverflow page looking for a something ala valueForKeyPath known from objc. I also came by another post - "Key-Value Coding" for Java, but ended up writing my own.

I'm still looking for at better solution than PropertyUtils.getProperty in apache's beanutils library.

Usage

Map<String, Object> json = ...
public String getOptionalFirstName() {
    return MyCode.getString(json, "contact", "firstName");
}

Implementation

public static String getString(Object object, String key0, String key1) {
    if (key0 == null) {
        return null;
    }
    if (key1 == null) {
        return null;
    }
    if (object instanceof Map == false) {
        return null;
    }
    @SuppressWarnings("unchecked")
    Map<Object, Object> map = (Map<Object, Object>)object;
    Object object1 = map.get(key0);
    if (object1 instanceof Map == false) {
        return null;
    }
    @SuppressWarnings("unchecked")
    Map<Object, Object> map1 = (Map<Object, Object>)object1;
    Object valueObject = map1.get(key1);
    if (valueObject instanceof String == false) {
        return null;
    }
    return (String)valueObject;
}
查看更多
甜甜的少女心
4楼-- · 2020-01-28 05:52

You can do it like you assumed. But your HashMap has to be templated:

Map<String, Map<String, String>> map = 
    new HashMap<String, Map<String, String>>();

Otherwise you have to do a cast to Map after you retrieve the second map from the first.

Map map = new HashMap();
((Map)map.get( "keyname" )).get( "nestedkeyname" );
查看更多
我只想做你的唯一
5楼-- · 2020-01-28 05:53

If you plan on constructing HashMaps with variable depth, use a recursive data structure.

Below is an implementation providing a sample interface:

class NestedMap<K, V> {

    private final HashMap<K, NestedMap> child;
    private V value;

    public NestedMap() {
        child = new HashMap<>();
        value = null;
    }

    public boolean hasChild(K k) {
        return this.child.containsKey(k);
    }

    public NestedMap<K, V> getChild(K k) {
        return this.child.get(k);
    }

    public void makeChild(K k) {
        this.child.put(k, new NestedMap());
    }

    public V getValue() {
        return value;
    }

    public void setValue(V v) {
        value = v;
    }
}

and example usage:

class NestedMapIllustration {
    public static void main(String[] args) {

        NestedMap<Character, String> m = new NestedMap<>();

        m.makeChild('f');
        m.getChild('f').makeChild('o');
        m.getChild('f').getChild('o').makeChild('o');
        m.getChild('f').getChild('o').getChild('o').setValue("bar");

        System.out.println(
            "nested element at 'f' -> 'o' -> 'o' is " +
            m.getChild('f').getChild('o').getChild('o').getValue());
    }
}
查看更多
登录 后发表回答