You can use the same strategy as multicolumn indexes in databases, if your key columns can be ordered (i.e., in Java, they need to be Comparable) and can easily define maximum and minimum values for all but the first.
An example with integer columns:
public class Key implements Comparable<Key> {
int c1, c2, c3;
private static final int c2_min = Integer.MIN_VALUE;
private static final int c2_max = Integer.MAX_VALUE;
private static final int c3_min = Integer.MIN_VALUE;
private static final int c3_max = Integer.MAX_VALUE;
@Override
public int compareTo(Key o) {
if (c1!=o.c1) return Integer.compare(c1, o.c1);
if (c2!=o.c2) return Integer.compare(c2, o.c2);
return Integer.compare(c3, o.c3);
}
// constructor, equals, ...
}
and then you can get all entries for some value k1 in c1 like this:
map.subMap(new Key(k1, Key.c2_min, 0), new Key(k1, Key.c2_max, 0));
Likewise, using the first two columns:
map.subMap(new Key(k1, k2, Key.c3_min), new Key(k1, k2, Key.c3_max));