我有一个Person
课程:
public class Person{
private String name;
//pleaese think this 'id' simply as an attribute of Person, same as e.g. age, height
private long id;
public Person(String name, long id){
this.name = name;
this.id = id;
}
public String getName(){
return name;
}
public long getId(){
return id;
}
}
然后,我有一个HashMap
实例,它可以从服务器中获取多个Person
的内容:
//key is String type, it is a unique name-like string assigned to each Person
//value is a Person object.
HashMap<String, Person> personsMap = GET_PERSONS_FROM_SERVER();
然后,我有一系列人员ID:
long[] ids = new long[]{1,2,3,4,5, …}
我需要的是生成另一个 HashMap
,其中只包含其ID列在ids
数组中的人员:
// Only the person whose id is listed in ids array will be in the following Map
Map<String, Person> personNeeded = … ;
如何以高效方式获取personNeeded
?
答案 0 :(得分:0)
您必须循环遍历所有Person对象并查找id匹配。当你找到它们时,你必须将它们添加到你的第二个HashMap中。
只要id只是Person对象的一个属性,你就必须循环遍历所有值,直到找到你想要的那些。
答案 1 :(得分:0)
您要么必须通过personsMap.values()
进行线性搜索,要么创建第二个Map
,这个Map
由您正在搜索的属性键入。
搜索Map
或线性搜索更快取决于您的使用案例。 Map
的构建速度很慢,但可以重复使用并提供快速查找。如果您需要进行多次(几次,真正的)搜索,请转到搜索personMap
路线。如果您只搜索{{1}}一次,只需要获得一个非常小的子集,那么就进行线性搜索。
答案 2 :(得分:0)
如果地图键与ID没有任何关系,那么没有比在地图条目上线性迭代更好地找到具有键的人的方法。
首先构建ID的集合数据结构,以便您可以在固定时间内检查人员的ID是否在列表中:
Set<Long> idSet = new HashSet<>();
for (long id: ids) idSet.add(id);
然后迭代条目:
HashMap<String, Person> personsById = new HashMap<>();
for (Map.Entry<String,Person> e : personsMap.entrySet()) {
String key = e.getKey();
Person val = e.getValue();
if (idSet.contains(val.getId()) personsById.put(key, val);
}
答案 3 :(得分:0)
这样做
Long[] ids = new Long[]{1l,2l,3l,4l,5l};
ArrayList<Long> idList = new ArrayList<Long>(Arrays.asList(ids));
HashMap<String, Person> personsMap = new HashMap<String, Person>();
HashMap<String, Person> newMap = new HashMap<String, Person>();
for (Map.Entry<String, Person> entry :personsMap.entrySet()) {
if(idList.contains(entry.getValue().getId())){
newMap.put(entry.getKey(), entry.getValue());
}
}
答案 4 :(得分:0)
你可以尝试一下这个:
1 - 将数组转换为Set
以进行快速查找
2 - 分配一个足够大的Map
以避免重新散列(对于默认的加载因子0.75,为所有元素的ID在集合中的最坏情况分配实际地图大小的4/3)< / p>
public void subMap(Map<String, Person> personMap, Long[] idArray) {
Set<Long> idSet = new HashSet<Long>(Arrays.asList(idArray));
Map<String, Person> personSubMap =
new HashMap<String, Person>((personMap.size() * 4 / 3) + 1);
for(Entry<String, Person> e : personMap.entrySet()) {
if(idSet.contains(e.getValue().getId())) {
personSubMap.put(e.getKey(), e.getValue());
}
}
}