这个问题和答案让我想出了这个解决方案:Type-safe object map。这是代码。测试用例:
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
public class TypedMapTest {
private final static TypedMapKey<String> KEY1 = new TypedMapKey<String>("key1");
private final static TypedMapKey<List<String>> KEY2 = new TypedMapKey<List<String>>("key2");
@Test
public void testGet() throws Exception {
TypedMap map = new TypedMap();
map.set(KEY1, null);
assertNull(map.get(KEY1));
String expected = "Hallo";
map.set(KEY1, expected);
String value = map.get(KEY1);
assertEquals(expected, value);
map.set(KEY2, null);
assertNull(map.get(KEY2));
List<String> list = new ArrayList<String>();
map.set(KEY2, list);
List<String> valueList = map.get(KEY2);
assertEquals(list, valueList);
}
}
Key类:
public class TypedMapKey<T> {
private String key;
public TypedMapKey(String key) {
this.key = key;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((key == null) ? 0 : key.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(obj == null) {
return false;
}
if(getClass() != obj.getClass()) {
return false;
}
TypedMapKey<?> other = (TypedMapKey<?>) obj;
if(key == null) {
if(other.key != null) {
return false;
}
} else if(!key.equals(other.key)) {
return false;
}
return true;
}
@Override
public String toString() {
return key;
}
}
TypedMap.java:
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class TypedMap implements Map<Object, Object> {
private Map<Object, Object> delegate;
public TypedMap(Map<Object, Object> delegate) {
this.delegate = delegate;
}
public TypedMap() {
this.delegate = new HashMap<Object, Object>();
}
@SuppressWarnings("unchecked")
public <T> T get(TypedMapKey<T> key) {
return (T) delegate.get(key);
}
@SuppressWarnings("unchecked")
public <T> T remove(TypedMapKey<T> key) {
return (T) delegate.remove(key);
}
public <T> void set(TypedMapKey<T> key, T value) {
delegate.put(key, value);
}
// --- Only calls to delegates below
public void clear() {
delegate.clear();
}
public boolean containsKey(Object key) {
return delegate.containsKey(key);
}
public boolean containsValue(Object value) {
return delegate.containsValue(value);
}
public Set<java.util.Map.Entry<Object, Object>> entrySet() {
return delegate.entrySet();
}
public boolean equals(Object o) {
return delegate.equals(o);
}
public Object get(Object key) {
return delegate.get(key);
}
public int hashCode() {
return delegate.hashCode();
}
public boolean isEmpty() {
return delegate.isEmpty();
}
public Set<Object> keySet() {
return delegate.keySet();
}
public Object put(Object key, Object value) {
return delegate.put(key, value);
}
public void putAll(Map<? extends Object, ? extends Object> m) {
delegate.putAll(m);
}
public Object remove(Object key) {
return delegate.remove(key);
}
public int size() {
return delegate.size();
}
public Collection<Object> values() {
return delegate.values();
}
}
如果该值本身是通用的,该怎么办?例如,不是存储`String`和`int`,你需要存储`PrettyPrinter`,其中`T`是用作映射中键的类型标记? –
Lucas
2012-07-14 22:33:57