0

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

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

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

最后,我希望用户搜索标题关键字“Loud Cars”。我会先在索引中找到“loud”得到[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 的值中?

4

3 回答 3

1

为“汽车”的索引条目添加一个新值

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"));
于 2013-11-12T00:23:59.373 回答
0

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

于 2013-11-12T00:15:34.100 回答
0

老实说,我认为扩展解决方案的最佳方法是使用布隆过滤器或类似的复杂工具。这将需要您创建复杂的哈希码、管理误报等。

话虽如此,根据您的设计,我认为您可以简单地将哈希映射指向也存储在数组列表中的 Disks 对象。

public HashMap<String, ArrayList<Disks>> map

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

确保覆盖 Disks 中的 hashCode() 和 equals() 以便所有集合都可以正常工作。

于 2013-11-12T00:23:50.693 回答