Wassim Sboui
Wassim Sboui

Reputation: 1820

Map with two Key for a value?

I want to create a map that has two key :

map.put (key1,key2,value1);// Insert into map
map.get(key1,key2); // return value1

i have looking into multikeyMap but i don't know how i will do it

Upvotes: 9

Views: 5394

Answers (7)

missingfaktor
missingfaktor

Reputation: 92056

It's unfortunate that Java does not support tuples at language level, and therefore you have to go for ad hoc structures like the ones showed in some answers here. This leads to atrocious amount of boilerplate and code duplication.

Functional Java has a library support for tuples. The class that fits the bill here is P2. The name means "product with 2 elements". (Product is just an algebraic term for composite types.) The library supports tuples of up to 8 elements. The P{n} classes override all the necessary methods

There is a class named P that provides a static factory method p for constructing tuples.

Usage:

import fj.P2;
import fj.Ord;
import fj.data.TreeMap;

import static fj.Ord.*;
import static fj.P.*;

TreeMap<P2<Integer, String>, String> m = 
  TreeMap.<P2<Integer, String>, String>empty(p2Ord(intOrd, stringOrd)).
  set(p(1, "2"), "onetwo").
  set(p(5, "3"), "fivethree");

Upvotes: 1

Manfred Moser
Manfred Moser

Reputation: 29912

If you always want to access via key1 and key2 together you could just concatenate them with a separator together as key and use a normal map.

Upvotes: 1

Louis Wasserman
Louis Wasserman

Reputation: 198103

If you can use outside libraries, Guava provides exactly this as Table<R, C, V>, referring to the two keys as "row" and "column" respectively. (Disclosure: I contribute to Guava.)

Upvotes: 2

Paul Bellora
Paul Bellora

Reputation: 55223

You might consider using one of Guava's Table implementations. From the documentation:

A collection that associates an ordered pair of keys, called a row key and a column key, with a single value. A table may be sparse, with only a small fraction of row key / column key pairs possessing a corresponding value.

Upvotes: 2

Jigar Joshi
Jigar Joshi

Reputation: 240898

How about

class Key{
 private final String key1;
 private final String key2;
//accessors + hashcode + equals()
}

and

Map<Key, Value> map

Upvotes: 10

Jon Skeet
Jon Skeet

Reputation: 1500725

Sounds like you just want a key which is created from two values. You may well find that those two values should naturally be encapsulated into another type anyway - or you could create a Key2<K1, K2> type. (The naming here would allow for Key3, Key4 etc. I wouldn't encourage you to go too far though.)

For something in between, you could create a private static class within the class where this is really needed (if it's only an internal implementation detail). If it's not a natural encapsulation (e.g. it's something like "name and population", which doesn't make sense outside this specific scenario) then it would be good in terms of keeping meaningful property names, but without exposing it publicly.

In any of these scenarios, you'll end up with a new type with two final variables which are initialized in the constructor, and which contribute to both equals and hashCode. For example:

public final class Key2<K1, K2> {
    private final K1 part1;
    private final K2 part2;

    public Key2(K1 part1, K2 part2) {
        this.part1 = part1;
        this.part2 = part2;
    }

    @Override public boolean equals(Object other) {
        if (!(other instanceof Key2)) {
            return false;
        }
        // Can't find out the type arguments, unfortunately
        Key2 rawOther = (Key2) other;
        // TODO: Handle nullity
        return part1.equals(rawOther.part1) &&
            part2.equals(rawOther.part2);
    }

    @Override public int hashCode() {
        // TODO: Handle nullity
        int hash = 23;
        hash = hash * 31 + part1.hashCode();
        hash = hash * 31 + part2.hashCode();
        return hash;
    }

    // TODO: Consider overriding toString and providing accessors.
}

The more situation-specific types would be slightly simpler as they wouldn't be generic - in particular this would mean you wouldn't need to worry about the type arguments, and you could give the variables better names.

Upvotes: 10

Gandalf StormCrow
Gandalf StormCrow

Reputation: 26212

Why not map key a String and concatinate key1+key2

Upvotes: 1

Related Questions