寻求一种有效的方法来生成我的HashMap实例

时间:2013-10-29 15:37:13

标签: java arrays hashmap

我有一个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

5 个答案:

答案 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());
        }
    }
}