创建HashMap作为标题关键字的索引,以提高搜索效率

时间:2013-11-12 00:04:06

标签: java search arraylist hashmap

我有一个自定义类Disks,它存储CD的各种信息,例如标题,长度,艺术家等。这些Disks对象存储在ArrayList中,只能包含元素添加了Disks。我正在使用一种方法来搜索这些对象的匹配标题。它接受用户输入,然后遍历列表的每个元素,并比较用户关键字和CD的标题。如果是完全匹配,则将其信息返回给用户。

我想通过合并HashMap来稍微改变这种搜索机制。我希望标记每个Disks标题,然后为关键字创建一个映射条目。

以下是一个示例:“汽车”一词出现在位置0,5,7的ArrayList元素的标题中。我希望能够为“Cars”创建一个映射条目,它将是一个列表[0,5,7]。如果另一个元素添加到位置10的ArrayList,标题中带有“Cars”,我将如何修改旧的映射条目,以便新列表为[0,5,7,10]?

最后,我希望用户搜索标题关键词“Loud Cars”。我将首先在索引中找到“响亮”以获取[0,7,5]的列表(例如),然后找到“cars”以获得[0,5,7,10]的列表。然后,我将找到这些列表相交的位置,并返回与这些位置对应的ArrayList元素。

我当前的HashMap声明如下所示:public HashMap<String, ArrayList<Integer>> map = new HashMap<>();但是即使Key不同,存储在ArrayList中的值也是相同的,因为它们只有一个。

我的Disks ArrayList是:public ArrayList<Disks> items;是否有办法将此ArrayList合并到HashMap的值中?

3 个答案:

答案 0 :(得分:1)

为“Cars”

的索引条目添加新值
map.get("Cars").add(10);

安全的方法(key =“Cars”,index = 10):

ArrayList<Integer> entry = map.get(key);
if (entry == null) {
  entry = new ArrayList<Integer>();
  map.put(key, entry);
}
entry.add(index);

而不是使用

HashMap<String, ArrayList<Integer>>

我建议

HashMap<String, HashSet<Integer>>

这会自动避免重复。

当您搜索多个单词时,使用retainAll构建多个集合的交集(但复制第一个集合,因为retainAll具有破坏性):

Set<Integer> resultSet = new HashSet<Integer>();
resultSet.addAll(map.get("Cars"));
resultSet.retainAll(map.get("Loud"));

答案 1 :(得分:0)

您需要为每个映射到值的字符串创建一个新的Integer ArrayList。第一次使用条目时,您创建一个新列表(您必须检查字符串映射为null),并将新磁盘条目将存储在Disls的ArrayList中的索引值添加到您的ArrayList整数。每当字符串映射到非空列表时,您只需将索引(它在Disk ArrayList中的位置)添加到Integer的ArrayList。

答案 2 :(得分:0)

老实说,我认为扩展解决方案的最佳方法是使用bloom过滤器或像这样复杂的东西。这需要您创建复杂的哈希码,管理误报等。

据说,根据您的设计,我认为您可以简单地使用指向同样存储在数组列表中的Disks对象的哈希映射。

public HashMap<String, ArrayList<Disks>> map

对于关键字“cars”,您有一个Disks对象列表。对于关键字“loud”,您有另一个Disks对象列表。只需使用retainAll()方法获取两个列表并找到交集。

确保在Disks中覆盖hashCode()和equals(),这样所有集合都可以正常工作。