You can look it up with an object that's equal to (as opposed to
identical to) the one embedded in the value. But you knew that.
Yes, and i tried not to think about it, because it's smelly. How do you
obtain these objects? Do you make them purely to use as key-holders? Does
that mean you're going to have half-filled-out instances of your value
class floating about the place? Does that mean you have to provide a
constructor that allows such instances to be created, so abandoning the
invariants that you could otherwise enforce through your constructors?
Or do you need to do something like:
public interface KeyHolder {
public String getKey();
}
public class Value implements KeyHolder {
private final String key;
// other fields
public String getKey() {
return key;
}
// other methods
}
public class Example implements KeyHolder { // so called for "query by example"
private final String key;
public Example(String key) {
this.key = key;
}
public String getKey() {
return key;
}
}
Map<KeyHolder, Value> objects = new TreeMap<KeyHolder, Value>(new Comparator<KeyHolder, KeyHolder>(){
public int compare(KeyHolder a, KeyHolder b) {
return a.getKey().compareTo(b.getKey());
}
});
Value v = ...;
String k = v.getKey();
objects.put(v, v);
Value u = objects.get(new Example(k));
assert u == v;
?
It can certainly be done, but all things considered, i lean towards
extracting the key before hitting the map. The map could perhaps be
wrapped in a simple wrapper:
public class ValueStore {
private Map<String, Value> map = new HashMap<String, Value>();
public void put(Value v) {
map.put(v.getKey(), v);
}
public Value get(String key) {
return map.get(key);
}
}
So that calling code is not troubled with the details.
tom