128

重複したキーを持つマップが必要です。

多くのマップ実装があることを知っているので (Eclipse は約 50 を示しています)、これを可能にするものがあるに違いありません。これを行う独自のマップを作成するのは簡単ですが、既存のソリューションを使用したいと思います。

commons-collections または google-collections の何かでしょうか。

4

19 に答える 19

93

マルチマップを探していますが、実際には commons-collections と Guava の両方にそのための実装がいくつかあります。マルチマップでは、キーごとに値のコレクションを維持することで、複数のキーを使用できます。つまり、単一のオブジェクトをマップに配置できますが、取得するのはコレクションです。

MultimapJava 5 を使用できる場合は、ジェネリックに対応しているため、Guava を使用することをお勧めします。

于 2009-06-30T10:44:40.260 に答える
34

Google コレクションの外部ライブラリに依存する必要はありません。次のマップを簡単に実装できます。

Map<String, ArrayList<String>> hashMap = new HashMap<String, ArrayList>();

public static void main(String... arg) {
   // Add data with duplicate keys
   addValues("A", "a1");
   addValues("A", "a2");
   addValues("B", "b");
   // View data.
   Iterator it = hashMap.keySet().iterator();
   ArrayList tempList = null;

   while (it.hasNext()) {
      String key = it.next().toString();             
      tempList = hashMap.get(key);
      if (tempList != null) {
         for (String value: tempList) {
            System.out.println("Key : "+key+ " , Value : "+value);
         }
      }
   }
}

private void addValues(String key, String value) {
   ArrayList tempList = null;
   if (hashMap.containsKey(key)) {
      tempList = hashMap.get(key);
      if(tempList == null)
         tempList = new ArrayList();
      tempList.add(value);  
   } else {
      tempList = new ArrayList();
      tempList.add(value);               
   }
   hashMap.put(key,tempList);
}

コードを微調整してください。

于 2011-06-15T02:57:14.017 に答える
19

通常の HashMap の値に値の配列を渡すだけで、重複キーをシミュレートできます。使用するデータを決定するのはユーザー次第です。

MultiMapを使用することもできますが、私自身は重複キーのアイデアは好きではありません。

于 2009-06-30T10:38:17.403 に答える
10

(コメントに書いたように)Key-Valueペアのリストについて反復したい場合は、リストまたは配列の方が適しているはずです。まず、キーと値を組み合わせます。

public class Pair
{
   public Class1 key;
   public Class2 value;

   public Pair(Class1 key, Class2 value)
   {
      this.key = key;
      this.value = value;
   }

}

Class1とClass2を、キーと値に使用するタイプに置き換えます。

これで、それらを配列またはリストに入れて、それらを反復処理できます。

Pair[] pairs = new Pair[10];
...
for (Pair pair : pairs)
{
   ...
}
于 2009-06-30T10:51:58.670 に答える
6

【2021年6月】

  1. org.springframework.util.MultiValueMap

  2. commons.apache.org - org.apache.commons.collections4

MultiValueMap クラス

于 2011-05-20T11:39:43.140 に答える
2

私はこの問題のわずかに異なるバリアントを持っていました: 2 つの異なる値を同じキーに関連付ける必要がありました。他の人に役立つ場合に備えてここに投稿するだけで、値として HashMap を導入しました。

/* @param frameTypeHash: Key -> Integer (frameID), Value -> HashMap (innerMap)
   @param innerMap: Key -> String (extIP), Value -> String
   If the key exists, retrieve the stored HashMap innerMap 
   and put the constructed key, value pair
*/
  if (frameTypeHash.containsKey(frameID)){
            //Key exists, add the key/value to innerHashMap
            HashMap innerMap = (HashMap)frameTypeHash.get(frameID);
            innerMap.put(extIP, connName+":"+frameType+":"+interfaceName);

        } else {
            HashMap<String, String> innerMap = new HashMap<String, String>();
            innerMap.put(extIP, connName+":"+frameType+":"+interfaceName);
            // This means the key doesn't exists, adding it for the first time
            frameTypeHash.put(frameID, innerMap );
        }
}

上記のコードでは、入力ファイルの各行の最初の文字列からキー frameID が読み取られます。frameTypeHash の値は、残りの行を分割することによって作成され、当初は String オブジェクトとして格納されていました。同じframeIDキーに関連付けられているため、frameTypeHashは値として最後の行で上書きされました。値フィールドとして String オブジェクトを別の HashMap オブジェクトに置き換えました。これは、単一のキーから異なる値へのマッピングを維持するのに役立ちました。

于 2014-08-02T12:40:59.567 に答える
1
class  DuplicateMap<K, V> 
{
    enum MapType
    {
        Hash,LinkedHash
    }

    int HashCode = 0;
    Map<Key<K>,V> map = null;

    DuplicateMap()
    {
        map = new HashMap<Key<K>,V>();
    }

    DuplicateMap( MapType maptype )
    {
        if ( maptype == MapType.Hash ) {
            map = new HashMap<Key<K>,V>();
        }
        else if ( maptype == MapType.LinkedHash ) {
            map = new LinkedHashMap<Key<K>,V>();
        }
        else
            map = new HashMap<Key<K>,V>();
    }

    V put( K key, V value  )
    {

        return map.put( new Key<K>( key , HashCode++ ), value );
    }

    void putAll( Map<K, V> map1 )
    {
        Map<Key<K>,V> map2 = new LinkedHashMap<Key<K>,V>();

        for ( Entry<K, V> entry : map1.entrySet() ) {
            map2.put( new Key<K>( entry.getKey() , HashCode++ ), entry.getValue());
        }
        map.putAll(map2);
    }

    Set<Entry<K, V>> entrySet()
    {
        Set<Entry<K, V>> entry = new LinkedHashSet<Map.Entry<K,V>>();
        for ( final Entry<Key<K>, V> entry1 : map.entrySet() ) {
            entry.add( new Entry<K, V>(){
                private K Key = entry1.getKey().Key();
                private V Value = entry1.getValue();

                @Override
                public K getKey() {
                    return Key;
                }

                @Override
                public V getValue() {
                    return Value;
                }

                @Override
                public V setValue(V value) {
                    return null;
                }});
        }

        return entry;
    }

    @Override
    public String toString() {
        StringBuilder builder = new  StringBuilder();
        builder.append("{");
        boolean FirstIteration = true;
        for ( Entry<K, V> entry : entrySet() ) {
            builder.append( ( (FirstIteration)? "" : "," ) + ((entry.getKey()==null) ? null :entry.getKey().toString() ) + "=" + ((entry.getValue()==null) ? null :entry.getValue().toString() )  );
            FirstIteration = false;
        }
        builder.append("}");
        return builder.toString();
    }

    class Key<K1>
    {
        K1 Key;
        int HashCode;

        public Key(K1 key, int hashCode) {
            super();
            Key = key;
            HashCode = hashCode;
        }

        public K1 Key() {
            return Key;
        }

        @Override
        public String toString() {
            return  Key.toString() ;
        }

        @Override
        public int hashCode() {

            return HashCode;
        }
    }
于 2016-04-01T07:04:01.913 に答える
0

キーが重複している場合、キーは複数の値に対応している可能性があります。明らかな解決策は、キーをこれらの値のリストにマップすることです。

たとえば、Pythonの場合:

map = dict()
map["driver"] = list()
map["driver"].append("john")
map["driver"].append("mike")
print map["driver"]          # It shows john and mike
print map["driver"][0]       # It shows john
print map["driver"][1]       # It shows mike
于 2009-06-30T19:50:43.533 に答える
0

念のために言うと、Apache Commons Collections にはMultiMapもあります。もちろん欠点は、Apache Commons が Generics を使用しないことです。

于 2009-06-30T19:30:25.757 に答える
0

少しハックすると、HashSet を重複キーで使用できます。警告: これは HashSet の実装に大きく依存します。

class MultiKeyPair {
    Object key;
    Object value;

    public MultiKeyPair(Object key, Object value) {
        this.key = key;
        this.value = value;
    }

    @Override
    public int hashCode() {
        return key.hashCode();
    }
}

class MultiKeyList extends MultiKeyPair {
    ArrayList<MultiKeyPair> list = new ArrayList<MultiKeyPair>();

    public MultiKeyList(Object key) {
        super(key, null);
    }

    @Override
    public boolean equals(Object obj) {
        list.add((MultiKeyPair) obj);
        return false;
    }
}

public static void main(String[] args) {
    HashSet<MultiKeyPair> set = new HashSet<MultiKeyPair>();
    set.add(new MultiKeyPair("A","a1"));
    set.add(new MultiKeyPair("A","a2"));
    set.add(new MultiKeyPair("B","b1"));
    set.add(new MultiKeyPair("A","a3"));

    MultiKeyList o = new MultiKeyList("A");
    set.contains(o);

    for (MultiKeyPair pair : o.list) {
        System.out.println(pair.value);
    }
}
于 2015-05-13T13:11:43.270 に答える
0

重複キーを使用してマップを実装しようとしているコンテキストについても説明できますか? より良い解決策があると確信しています。マップは、正当な理由で一意のキーを保持することを目的としています。あなたが本当にやりたかったのなら。クラスをいつでも拡張して、衝突軽減機能を持ち、同じキーで複数のエントリを保持できるようにする単純なカスタム マップ クラスを作成できます。

注: 衝突するキーが「常に」一意のセットに変換されるように、衝突緩和機能を実装する必要があります。オブジェクトのハッシュコードなどでキーを追加するような単純なものはありますか?

于 2009-06-30T10:41:32.560 に答える
0

私はこれを使用しました:

java.util.List<java.util.Map.Entry<String,Integer>> pairList= new java.util.ArrayList<>();

于 2016-02-02T16:28:33.933 に答える