How to implement a Map with multiple keys? [duplic

2019-01-01 00:12发布

This question already has an answer here:

I need a data structure which behaves like a Map, but uses multiple (differently-typed) keys to access its values.
(Let's not be too general, let's say two keys)

Keys are guaranteed to be unique.

Something like:

MyMap<K1,K2,V> ...

With methods like:

getByKey1(K1 key)...
getByKey2(K2 key)...
containsKey1(K1 key)...
containsKey2(K2 key)...

Do you have any suggestions?

The only thing I can think of is:
Write a class which uses two Maps internally.

EDIT Some people suggest me to use a tuple, a pair, or similar as a key for Java's Map, but this would not work for me:
I have to be able, as written above, to search values by only one of the two keys specified.
Maps use hash codes of keys and check for their equality.

27条回答
闭嘴吧你
2楼-- · 2019-01-01 00:49

How about using a trie data structure ?

http://en.wikipedia.org/wiki/Trie

The root of the trie will by blank. The first level siblings will be your primary keys of the map, the second level siblings will be your secondary keys and the third level will be the terminal nodes which will have the value along will null to indicate termination of that branch. You can also add more than two keys using the same scheme.

Look up is simple DFS.

查看更多
初与友歌
3楼-- · 2019-01-01 00:52

I created this to solve a similar issue.

Datastructure

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

public class HashBucket {
    HashMap<Object, ArrayList<Object>> hmap;

    public HashBucket() {
        hmap = new HashMap<Object, ArrayList<Object>>();
    }

    public void add(Object key, Object value) {
        if (hmap.containsKey(key)) {
            ArrayList al = hmap.get(key);
            al.add(value);
        } else {
            ArrayList al = new ArrayList<Object>();
            al.add(value);
            hmap.put(key, al);
        }
    }

    public Iterator getIterator(Object key) {
        ArrayList al = hmap.get(key);
        return hmap.get(key).iterator();

    }

}

Retrieve a value:

(Note* Cast the Object back to the inserted type. In my case it was my Event Object)

    public Iterator getIterator(Object key) {
        ArrayList al = hmap.get(key);
        if (al != null) {
            return hmap.get(key).iterator();
        } else {
            List<Object> empty = Collections.emptyList();
            return empty.iterator();
        }

    }

Inserting

Event e1 = new Event();
e1.setName("Bob");
e1.setTitle("Test");
map.add("key",e1);
查看更多
情到深处是孤独
4楼-- · 2019-01-01 00:53

Both MultiMap or MultiKeyMap from Commons or Guava will work.

However, a quick and simple solution could be to extend Map class buy handling a composite key yourself, considering that keys are of primitive type.

查看更多
无与为乐者.
5楼-- · 2019-01-01 00:54

Yet another solution is to use Google's Guava

import com.google.common.collect.Table;
import com.google.common.collect.HashBasedTable;

Table<String, String, Integer> table = HashBasedTable.create();

The usage is really simple:

String row = "a";
String column = "b";
int value = 1;

if (!table.contains(row, column)) {
    table.put(row, column, value);
}

System.out.println("value = " + table.get(row, column));

The method HashBasedTable.create() is basically doing something like this:

Table<String, String, Integer> table = Tables.newCustomTable(
        Maps.<String, Map<String, Integer>>newHashMap(),
        new Supplier<Map<String, Integer>>() {
    public Map<String, Integer> get() {
        return Maps.newHashMap();
    }
});

if you're trying to create some custom maps, you should go for the second option (as @Karatheodory suggests) otherwise you should be fine with the first one.

查看更多
泛滥B
6楼-- · 2019-01-01 00:54

sol: cancatenate both keys and make a final key, use this as key.

for key values ,

concatenate ket-1, and key-2 with a come " , " in beetween, use this as original key.

key = key-1 + "," + key-2;

myMap.put(key,value);

similarly while retriving values.

查看更多
旧人旧事旧时光
7楼-- · 2019-01-01 00:54

I would suggest the structure

Map<K1, Map<K2, V>>

although searching for the second key might not be efficient

查看更多
登录 后发表回答