如何在Java中访问嵌套的HashMaps?

时间:2010-05-05 15:32:12

标签: java hashmap

我在Java中有一个HashMap,其中的内容(大家都知道)可以通过

访问
HashMap.get("keyname");

如果一个HashMap在另一个HashMap中,即一个嵌套的HashMap,我将如何访问内容?我能这样做吗,内联:

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

谢谢。

11 个答案:

答案 0 :(得分:61)

你可以像你假设的那样做。但你的HashMap必须模板化:

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

否则,在从第一张地图中检索第二张地图后,您必须对Map进行投射。

Map map = new HashMap();
((Map)map.get( "keyname" )).get( "nestedkeyname" );

答案 1 :(得分:8)

见:

public static void main(String args[]) {

    HashMap<String, HashMap<String, Object>> map = new HashMap<String, HashMap<String,Object>>();
    map.put("key", new HashMap<String, Object>());
    map.get("key").put("key2", "val2");

    System.out.println(map.get("key").get("key2"));
}

答案 2 :(得分:5)

正如其他人所说,你可以这样做,但你应该用这样的泛型来定义地图:

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

但是,如果你只是盲目地运行以下内容:

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

只要keyname不在地图中,你的程序就会崩溃,你会得到一个空指针异常。你真的应该添加以下检查:

String valueFromMap = null;
if(map.containsKey("keyname")){
  valueFromMap = map.get("keyname").get("nestedkeyname");
}

答案 3 :(得分:5)

如果您计划构建具有可变深度的HashMaps ,请使用递归数据结构

以下是提供示例界面的实现:

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

和示例用法:

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

答案 4 :(得分:4)

是的,如果您对外部hashmap使用正确的泛型类型签名。

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

如果您不使用泛型,则必须先进行强制转换才能将从外部哈希映射中检索到的对象转换为HashMap(或至少为Map)调用它的get()方法。但你应该使用泛型; - )

答案 5 :(得分:3)

我更喜欢创建一个扩展HashMap的自定义地图。然后重写get()以添加额外的逻辑,以便在地图不包含您的密钥时。它将创建嵌套地图的新实例,添加它,然后返回它。

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

现在您可以这样使用它:

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

答案 6 :(得分:2)

我来到这个StackOverflow页面,寻找objc中已知的ala valueForKeyPath。我也来了另一篇文章 - "Key-Value Coding" for Java,但最终写了我自己的帖子。

我仍然希望在apache的PropertyUtils.getProperty库中找到比beanutils更好的解决方案。

用法

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

实施

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

答案 7 :(得分:1)

您可以通过重复.get()来获取嵌套值,但是对于深度嵌套的地图,您必须进行大量转换为Map。一种更简单的方法是使用通用方法来获取嵌套值。

实施

public static <T> T getNestedValue(Map map, String... keys) {
    Object value = map;

    for (String key : keys) {
        value = ((Map) value).get(key);
    }

    return (T) value;
}

用法

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

答案 8 :(得分:0)

import java.util.*;
public class MyFirstJava {
public static void main(String[] args)
{
  Animal dog = new Animal();
  dog.Info("Dog","Breezi","Lab","Chicken liver");
  dog.Getname();
  Animal dog2= new Animal();
  dog2.Info("Dog", "pumpkin", "POM", "Pedigree");
  dog2.Getname();
  HashMap<String,  HashMap<String, Object>> dogs = new HashMap<>();
  dogs.put("dog1", new HashMap<>() {{put("Name",dog.name); 
  put("Food",dog.food);put("Age",3);}});
  dogs.put("dog2", new HashMap<>() {{put("Name",dog2.name); 
  put("Food",dog2.food);put("Age",6);}});
  //dogs.get("dog1");
  System.out.print(dogs + "\n");
  System.out.print(dogs.get("dog1").get("Age"));

}    }

答案 9 :(得分:0)

示例地图:

{
    "data": {
        "userData": {
            "location": {
                "city": "Banja Luka"
            }
        }
    }
}

实施: { "data": { "userData": { "location": { "city": "Banja Luka" } } } }

用法:


    final Map data = new HashMap();
    final Map userData = new HashMap();
    final Map location = new HashMap();
    
    location.put("city", "Banja Luka");
    userData.put("location", location);
    data.put("userData", userData);
    
    System.out.println(getValueFromMap(data, "userData.location.city"));

    Banja Luka

    Process finished with exit code 0

答案 10 :(得分:-1)

我在尝试讨论如何从未知深度的嵌套映射中获取值时进行了讨论,它帮助我提出了以下解决问题的方法。对于最初的问题来说,这太过分了,但是对于发现自己对所搜索地图知之甚少的人来说,这可能会有所帮助。

private static Object pullNestedVal(
        Map<Object, Object> vmap,
        Object ... keys) {
    if ((keys.length == 0) || (vmap.size() == 0)) {
        return null;
    } else if (keys.length == 1) {
        return vmap.get(keys[0]);
    }

    Object stageObj = vmap.get(keys[0]);
    if (stageObj instanceof Map) {
        Map<Object, Object> smap = (Map<Object, Object>) stageObj;
        Object[] skeys = Arrays.copyOfRange(keys, 1, keys.length);
        return pullNestedVal(smap, skeys);
    } else {
        return null;
    }
}