我有一个 Java 中的 HashMap,其内容(正如大家可能知道的那样)可以通过
HashMap.get("keyname");
如果我有一个嵌套的HashMap,也就是一个HashMap里面还包含另一个HashMap,我该如何访问其中的内容?我能够像这样内联方式进行访问吗:
HashMap.get("keyname").get("nestedkeyname");
谢谢您。你可以像你所想的那样做。但是你的HashMap必须是有模板的:
Map<String, Map<String, String>> map =
new HashMap<String, Map<String, String>>();
否则,您需要在从第一个地图检索第二个地图后进行Map
转换。Map map = new HashMap();
((Map)map.get( "keyname" )).get( "nestedkeyname" );
new HashMap<>();
吗?这样可以少打几个字...(可能是在1.8版本之前问的,那时候这么做是可行的)。 - JGFMK您可以通过重复使用 .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");
是的。
可以参见:
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"));
}
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());
}
}
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");
}
是的,如果你在外部哈希映射表中使用适当的泛型类型签名。
HashMap<String, HashMap<String, Foo>> hm = new HashMap<String, HashMap<String, Foobar>>();
// populate the map
hm.get("keyname").get("nestedkeyname");
如果您没有使用泛型,那么您需要进行转换才能从外部哈希映射中检索到的对象转换为HashMap
(或至少是Map
),然后才能调用其get()
方法。但是您应该使用泛型 ;-)
我建议创建一个继承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);
valueForKeyPath
的东西。我也看到了另一篇帖子 - Java的"Key-Value Coding",但最终我还是写了自己的代码。beanutils
库中的PropertyUtils.getProperty
更好的解决方案。
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;
}
示例地图:
{
"data": {
"userData": {
"location": {
"city": "Banja Luka"
}
}
}
}
实现:
public static Object getValueFromMap(final Map<String, Object> map, final String key) {
try {
final String[] tmpKeys = key.split("\\.");
Map<String, Object> currentMap = map;
for (int i = 0; i < tmpKeys.length - 1; i++) {
currentMap = (Map<String, Object>) currentMap.get(tmpKeys[i]);
}
return currentMap.get(tmpKeys[tmpKeys.length - 1]);
} catch (Exception exception) {
return null;
}
}
用法:
final Map<String, Object> data = new HashMap<>();
final Map<String, Object> userData = new HashMap<>();
final Map<String, Object> 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
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"));
}
valueForKeyPath
,Java也有类似的功能,请参考https://dev59.com/rEnSa4cB1Zd3GeqPSOpp。 - neoneye