我的应用程序中有两张地图,让它成为'id by id'和'manager by id'。我使用它们来获取用户ID:
Map<Id, Person> usersById = new HashMap<Id, Person>();
Map<Id, Person> managersById = new HashMap<Id, Person>();
Person me = usersById.get(myId);
这两个实体都是人,所以有时我需要通过其ID找到一个任意人。是的,我可以在一张地图中搜索,然后在另一张地图中搜索:
Person findArbitraryPerson(Id id) {
Person candidate = usersById.get(myId);
if (candidate == null) {
candidate = managersById.get(myId);
}
return candidate;
}
但是,可能有更好的方法吗? 是的,我可以创建一个公共人员地图。但是我每次到达时都要向该地图添加一个新的Person实例,并将其删除等。是否有可能创建一种“由两个地图支持”的地图,以自动更新内容?正如我可以在集合框架中创建由原始地图支持的子地图。
或者,可能有更好的解决方案吗?
答案 0 :(得分:3)
我的comment和@ BrianRoach comment的扩展(和/或结论):
public abstract class Person {
// general members and methods shared by managers and users
}
public class User extends Person {
// User specific members and methods
}
public class Manager extends Person {
// Manager specific members and methods
}
Map<Id,Person> map = new HashMap<Id, Person>();
map.put(new Id(), new Manager());
map.put(new Id(), new User());
OR(如果你是如此倾向),只需在Person对象上有一个布尔成员:isManager
并使用适当的getter / setter。
答案 1 :(得分:1)
这是一个只读地图(未经测试!),由任意数量的其他地图备份:
private class ReadonlyProxyMap<K, V> implements Map<K, V> {
private final List<Map<K, V>> maps = new ArrayList<>();
public void addMap(Map<K, V> map) {
maps.add(map);
}
@Override
public int size() {
return entrySet().size();
}
@Override
public boolean isEmpty() {
for (Map<K, V> map : maps) {
if (!map.isEmpty()) {
return false;
}
}
return true;
}
@Override
public boolean containsKey(Object key) {
for (Map<K, V> map : maps) {
if (map.containsKey(key)) {
return true;
}
}
return false;
}
@Override
public boolean containsValue(Object value) {
for (Map<K, V> map : maps) {
if (map.containsValue(value)) {
return true;
}
}
return false;
}
@Override
public V get(Object key) {
for (Map<K, V> map : maps) {
if (map.containsKey(key)) {
return map.get(key);
}
}
return null;
}
@Override
public V put(K key, V value) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public V remove(Object key) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void putAll(Map<? extends K, ? extends V> m) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void clear() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public Set<K> keySet() {
Set<K> keySet = new HashSet<>();
for (Map<K, V> map : maps) {
keySet.addAll(map.keySet());
}
return keySet;
}
@Override
public Collection<V> values() {
List<V> values = new ArrayList<>();
for (Map.Entry<K, V> entry : entrySet()) {
values.add(entry.getValue());
}
return values;
}
@Override
public Set<Map.Entry<K, V>> entrySet() {
Set<K> keySet = new HashSet<>();
Set<Map.Entry<K, V>> entrySet = new HashSet<>();
for (Map<K, V> map : maps) {
for (Map.Entry<K, V> entry : map.entrySet()) {
if (!keySet.contains(entry.getKey())) {
entrySet.add(entry);
keySet.add(entry.getKey());
}
}
}
return entrySet;
}
}
然后你可以使用:
Map<Id, Person> usersById = new HashMap<>();
Map<Id, Person> managersById = new HashMap<>();
ReadonlyProxyMap<Id, Person> allPersons = new ReadonlyProxyMap<>();
...
allPersons.addMap(usersById);
allPersons.addMap(managersById);
...
Person findArbitraryPerson(Id id) {
return allPersons.get(myId);
}
答案 2 :(得分:0)
当然经理人也是人?更好的方法是制作Person
s的地图,并Manager
展开Person
。
让某人查询地图并返回找到的Person
。让管理器查询映射并检查返回的对象是否为Manager
的实例,如果不是则返回null。
我会将整个HashMap
包装到您自己的类中,该类应该使用适当的调用/检查来实现getPerson()
,getManager()
,getUser()
。这也将API与实现分离,因此将来您可以随时更改它,而不必更改任何其他代码。