1

我有一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从服务器获取的多个 s:

//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有效的方式获得?

4

5 回答 5

0

If the map keys are not related in any way to the IDs, there is no better way to find the persons with the keys better than a linear iteration over the map entries.

First construct a set data structure of the IDs so you can check if the ID of a person is in the list in constant time:

Set<Long> idSet = new HashSet<>();
for (long id: ids) idSet.add(id);

Then just iterate over the entries:

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);
}
于 2013-10-29T15:56:00.060 回答
0

你可以尝试这样的事情:

1 - 将您的数组转换Set为快速查找

2 - 分配Map足够大的空间以避免重新散列(对于默认加载因子 0.75,为所有元素的 id 都在集合中的最坏情况分配实际地图大小的 4/3)

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());
        }
    }
}
于 2013-10-29T16:02:16.290 回答
0

您必须遍历所有 Person 对象并查找 id 匹配项。当您找到它们时,您必须将它们添加到您的第二个 HashMap 中。

只要 id 只是 Person 对象的一个​​属性,您就必须遍历所有值,直到找到您要查找的值。

于 2013-10-29T15:44:09.287 回答
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());
      }
}
于 2013-10-29T15:57:23.477 回答
0

您要么必须进行线性搜索,personsMap.values()要么创建一个Map由您正在搜索的属性键入的第二个。

搜索Map或线性搜索是否更快取决于您的用例。 Maps 构建起来可能很慢,但它们可以被重复使用并提供非常快速的查找。如果您需要进行多次(实际上是多次)搜索,请选择搜索Map路线。如果您personMap只搜索一次并且只需要获得一个非常小的子集,那么进行线性搜索。

于 2013-10-29T15:50:03.807 回答