web-dev-qa-db-ja.com

JavaでネストされたHashMapにアクセスするにはどうすればよいですか?

JavaのHashMapがあり、その内容には(おそらくご存知のように)アクセスできます

HashMap.get("keyname");

別のHashMap内にHashMapがある場合、つまりネストされたHashMapがある場合、どのようにコンテンツにアクセスしますか?これをインラインで行うことができます:

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

ありがとうございました。

29

想定どおりにできます。ただし、HashMapはテンプレート化する必要があります。

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

それ以外の場合は、最初のマップから2番目のマップを取得した後、Mapにキャストする必要があります。

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

はい。

見る:

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"));
}
8
Benjamin Borden

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

他の人が言ったように、あなたはこれを行うことができますが、次のようなジェネリックでマップを定義する必要があります:

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

ただし、盲目的に次を実行する場合:

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

キー名がマップにない場合は常にNULLポインター例外が発生し、プログラムがクラッシュします。次のチェックを追加する必要があります。

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

はい、外側のハッシュマップに適切なジェネリック型シグネチャを使用する場合。

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

ジェネリックを使用していない場合は、外部ハッシュマップから取得したオブジェクトをHashMap(または少なくともMap)に変換してから呼び出す必要があります。 get()メソッド。しかし、ジェネリックを使用する必要があります;-)

4
David Z

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);
3
Cody Wagner

このStackOverflowページにアクセスして、objcから既知のala valueForKeyPathを探しました。また、別の投稿- Javaの「キー値コーディング」 がありましたが、最終的には自分で書きました。

Apacheの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;
}
2
neoneye