即使没有“映射”,也使用Java哈希映射?

时间:2009-12-29 23:32:06

标签: java data-structures hashtable hashmap hash

我想存储一些对象,然后能够尽可能高效地检索它们。我也会在某些条件下删除其中一些。看起来哈希映射是正确的选择。

但是,从我所看到的,哈希映射总是将值与另一个值相关联?例如,“john”和“555-5555”,他的电话号码。

现在,我的情况。假设我有一群人,每个人都与其他人联系在一起。所以,我需要每个人都存储其联系人。

我正在做的是让每个人都有一个hashmap,然后我将添加到hash otherersPerson,otherPerson。基本上,关键是价值。我做错了吗?

编辑我不认为HashSet会解决我的问题,因为我必须检索值来更新它并且没有get方法。删除返回一个布尔值,所以我甚至无法将其删除以将其重新放回,这无论如何都可能是一个坏主意。

7 个答案:

答案 0 :(得分:3)

如果你只需要检查A是否是B的联系人之一,那么Set就是选择。它为此目的包含()。

否则,最合适的可能是Map,因为您需要高效的检索操作。你说当前你使用相同的对象作为键和值,但我不确定你是如何获得密钥的。假设您想从B的联系人那里获得联系人A,并使用“B.contacts.get(A)”之类的内容,您从哪里获得A?如果你已经拥有A,那又有什么可以从地图上获取它? (也许同一个人有多个实例?)

除非同一个人有多个实例,否则我会为每个人定义一个类似于唯一属性的ID,并将其用作联系人地图的关键字。另外,你为person类定义了equal()/ hashCode()吗? Map / Set使用hashCode()和equal()来查找匹配。根据您的使用情况,您可能需要考虑重写它们以提高效率。

答案 1 :(得分:2)

嗯,你在这里寻找的数据结构,是一个HashSet(或其他类型的集合),我想(如果你的框架/库提供它)。一组只是说“我有以下项目”而不是“我将以下项目映射到以下值”。这就是你在这里建模的内容。

至于HashSet与其他实现(如果存在):这完全取决于你正在做什么。如果你需要快速查找,我。即“这是集合中的这个元素吗?”问题,然后哈希是一件好事。其他底层数据结构可能更适合其他集合操作,例如union,intersection等。

答案 2 :(得分:2)

哈希表/地图只需要您有办法获得您以后想要查找的值;这就是关键所在。

然而,在您的具体情况下,听起来您正在寻找一种存储人与人之间关系的方式,而您所追踪的是A人是否与B有关系。对于那种事情是 adjacency list

答案 3 :(得分:2)

  

我不认为HashSet会解决我的问题,因为我必须检索值来更新它并且没有get方法。

这是一个令人费解的声明。为什么要使用get方法检索值来更新它?当然,如果您知道需要从集合/地图中检索哪个对象,则无需检索它。

例如:

HashSet<Person> relations = ...
Person p = ...
if (relations.remove(p)) {
    // we removed an object such that p.equals(obj) is true.
}

现在,如果您担心被删除的对象等于,但 p不同,那么在我看来您的设计有问题。之一:

  • 您不应该创建相同的多个Person实例,或
  • 你不应该关心Person实例不相同,或
  • 你不应该覆盖equals(Object)

简而言之,问题在于您没有正确管理对象标识。

答案 4 :(得分:0)

我错过了什么或者你不是只需要一个ArrayList<Person>吗?

答案 5 :(得分:0)

我只会将联系人存储在List<Person>中。 E.g。

public class Person {
    private List<Person> contacts;
}

关于编辑个人联系人,实际上并非父Person负责。它应该在最高添加/删除联系人。您可以通过contacts.add(otherPerson)contacts.remove(otherPerson)完美地完成此任务。

当您想要编辑可能是其中一个联系人的个人Person时,只需单独处理它,例如personDAO.find(personId)然后相应地更新它。它实际上也是Person自己负责编辑自己的细节。通过良好的ORM,更改将反映在其他Person的联系人列表中。

答案 6 :(得分:0)

如果您需要遍历人员,或要求他们进行排序,请考虑使用TreeMap或TreeSet而不是散列。