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:56

Another possile solution providing the possibility of more complicated keys can be found here: http://insidecoffe.blogspot.de/2013/04/indexable-hashmap-implementation.html

查看更多
梦醉为红颜
3楼-- · 2019-01-01 00:56

How about something like this:

His statement says that keys are Unique, so saving the same value objects against different keys is quite possible and when you send any key matching the said value, we would be able to get back to the value object.

See code below:

A value Object Class,

    public class Bond {
    public Bond() {
        System.out.println("The Name is Bond... James Bond...");
    }
    private String name;
    public String getName() { return name;}
    public void setName(String name) { this.name = name; }
}

public class HashMapValueTest {

    public static void main(String[] args) {

        String key1 = "A";
        String key2 = "B";
        String key3 = "C";

        Bond bond = new Bond();
        bond.setName("James Bond Mutual Fund");

        Map<String, Bond> bondsById = new HashMap<>();

        bondsById.put(key1, bond);
        bondsById.put(key2, bond);
        bondsById.put(key3, bond);

        bond.setName("Alfred Hitchcock");

        for (Map.Entry<String, Bond> entry : bondsById.entrySet()) {
            System.out.println(entry.getValue().getName());
        }

    }

}

The result is:

The Name is Bond... James Bond...

Alfred HitchCock

Alfred HitchCock

Alfred HitchCock
查看更多
美炸的是我
4楼-- · 2019-01-01 00:59

Depending on how it will be used, you can either do this with two maps Map<K1, V> and Map<K2, V> or with two maps Map<K1, V> and Map<K2, K1>. If one of the keys is more permanent than the other, the second option may make more sense.

查看更多
查无此人
5楼-- · 2019-01-01 01:01

Two maps. One Map<K1, V> and one Map<K2, V>. If you must have a single interface, write a wrapper class that implements said methods.

查看更多
大哥的爱人
6楼-- · 2019-01-01 01:02

all multy key's probably fail, cause the put([key1, key2], val) and the get([null, key2]) end up using the equals of [key1, key2] and [null, key2]. If the backing map doesnt contains hash buckets per key then lookups are real slow to.

i think the way to go is using a index decorator (see the key1, key2 examples above) and if the extra index key's are properties of the stored value you can use the property name's and reflection to build the secondairy maps when you put(key, val) and add an extra method get(propertyname, propertyvalue) to use that index.

the return type of the get(propertyname, propertyvalue) could be a Collection so even none unique key's are indexed....

查看更多
浮光初槿花落
7楼-- · 2019-01-01 01:02

If you intend to use combination of several keys as one, then perhaps apache commnons MultiKey is your friend. I don't think it would work one by one though..

查看更多
登录 后发表回答