How do I access nested HashMaps in Java?

后端 未结 10 766
再見小時候
再見小時候 2020-12-01 09:28

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

相关标签:
10条回答
  • 2020-12-01 09:37

    I prefer creating a custom map that extends HashMap. Then just override get() to add extra logic so that if the map doesnt contain your key. It will a create a new instance of the nested map, add it, then return it.

    public class KMap<K, V> extends HashMap<K, V> {
    
        public KMap() {
            super();
        }
    
        @Override
        public V get(Object key) {
            if (this.containsKey(key)) {
                return super.get(key);
            } else {
                Map<K, V> value = new KMap<K, V>();
                super.put((K)key, (V)value);
                return (V)value;
            }
        }
    }
    

    Now you can use it like so:

    Map<Integer, Map<Integer, Map<String, Object>>> nestedMap = new KMap<Integer, Map<Integer, Map<String, Object>>>();
    
    Map<String, Object> map = (Map<String, Object>) nestedMap.get(1).get(2);
    Object obj= new Object();
    map.put(someKey, obj);
    
    0 讨论(0)
  • 2020-12-01 09:43

    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());
        }
    }
    
    0 讨论(0)
  • 2020-12-01 09:47

    You can get the nested value by repeating .get(), but with deeply nested maps you have to do a lot of casting into Map. An easier way is to use a generic method for getting a nested value.

    Implementation

    public static <T> T getNestedValue(Map map, String... keys) {
        Object value = map;
    
        for (String key : keys) {
            value = ((Map) value).get(key);
        }
    
        return (T) value;
    }
    

    Usage

    // Map contents with string and even a list:
    {
      "data": {
        "vehicles": {
          "list": [
            {
              "registration": {
                "owner": {
                  "id": "3643619"
                }
              }
            }
          ]
        }
      }
    }
    
    List<Map> list = getNestedValue(mapContents, "data", "vehicles", "list");
    Map first = list.get(0);
    String id = getNestedValue(first, "registration", "owner", "id");
    
    0 讨论(0)
  • 2020-12-01 09:48

    Yes, if you use the proper generic type signature for the outer hashmap.

    HashMap<String, HashMap<String, Foo>> hm = new HashMap<String, HashMap<String, Foobar>>();
    // populate the map
    hm.get("keyname").get("nestedkeyname");
    

    If you're not using generics, you'd have to do a cast to convert the object retrieved from the outer hash map to a HashMap (or at least a Map) before you could call its get() method. But you should be using generics ;-)

    0 讨论(0)
提交回复
热议问题