如何不断更新HashMap,其中Key和Value都是Java中的ArrayLists

时间:2017-07-30 07:39:49

标签: java arraylist hashmap

我正在开展一个项目,该项目涉及一些工作的数据集的微小组合和关联,并且已经停留了一段时间。

我有一组数据,类似于项目中的其他数据组。我有一个组名的数组列表。我将这些类似的组与其他数据集进行比较,描述类似的事情。 (一组组,与其自己的集合中的其他组类似)。

我一直试图通过使用:

来解决这个问题
HashMap<ArrayList<String>, ArrayList<String>>

当找到另一个关系时,证明很难添加另一个组(按名称,字符串)。

如果我从每个数据集中找到另一个组并想要添加到当前的ArrayList(这就是我使用ArrayLists的原因),它会创建另一个条目,其中新的键和值与前一个相同但添加了每个ArrayList中的元素。

以下是当前的相关代码:

... 
for(ArrayList<String> similarGroupsDataset : map.keySet()) {
    ...
        ArrayList<String> value = map.get(similarGroupsDataset);
        ArrayList<String> key = similarGroups;
        value.add(groupToAdd);
        key.add(groupToAdd2);
        map.remove(similarGroupsDataset);
        map.put(key, value);
}

将ArrayList键和Arraylist值存储到变量中,添加新找到的数据,删除旧条目,然后添加更新版本。

由于某种原因,此接缝不会删除没有新添加的找到数据的条目。

因此,如果我打印出地图,它看起来就像 ({1,2},{a,b}),({1,2,3},{a,b,c}) 应该是什么样的 ({1,2,3},{a,b,c}),取出不相关的条目。 数据集1中的1,2是相似的,如果有意义,它们仍然与数据集2中的a,b相似。

我试过

map.get(relevantGroupFromDataset2).add(data) 
//adds the newly found similar group to the list of groups 
//which are all similar to eachother, from dataset1.

有时会起作用,但似乎只是价值,而不是关键。

最后,我的目标是使用一个标识符重新创建这些数据集,这些标识符通过一个新标识符将这些组绑定在一起,而不是它们当前的标识符,它们不会按照我想要的方式将它们绑定在一起。

我在这里做错了吗?在这种情况下是否有更好的数据结构?是一种HashMap或类似的结构吗?

3 个答案:

答案 0 :(得分:1)

  

如果我从每个数据集中找到另一个组并想要添加到当前   ArrayList(这就是我使用ArrayLists的原因),它创建了另一个   输入,其中新键和值与前一个相同但是   使用每个ArrayList中添加的元素。

您使用ArrayList作为键 在地图中,密钥是从hashCode()/equals()方法中检索的 因此,当您在此处更改ArrayList键的内容时:

ArrayList<String> value = map.get(similarGroupsDataset);
ArrayList<String> key = similarGroups;
value.add(groupToAdd);
key.add(groupToAdd2); // <-- here

hashCode()equals()不会再产生相同的结果。
它被认为是地图的新关键。

所以map.put(key, value);会添加一个新元素。

根据Map执行的逻辑以及您期望的内容实际上并不清楚,为您提供实际代码的良好解决方案并不明显。 例如:

value.add(groupToAdd);
key.add(groupToAdd2);

是一个非常糟糕的命名,或者只使用组填充地图的键值。

一般的想法是,您不应该在地图中使用hashCode()/ equals()结果可能会在地图中添加了密钥后更改的密钥。
要实现它:

  • 在您知道密钥不再被修改的时候,将值与ArrayList键放在一起。

  • 使用键删除值,然后使用新键重新添加。

在任何情况下,为了避免这种错误,您应该为密钥创建一个不可修改的List并将其传递给地图:

map.put(Collections.unmodifiableList(keys), ...);

答案 1 :(得分:0)

通过key.add(groupToAdd2);更改,但地图的键必须是有效的不可变的:

  

Note: great care must be exercised if mutable objects are used as map keys. The behavior of a map is not specified if the value of an object is changed...

交换行key.add(groupToAdd2);map.remove(similarGroupsDataset);以解决此问题,甚至更好:

...
for (Entry<ArrayList<String>, ArrayList<String>> entry : map.entrySet()) {
    ... 
        map.remove(entry.getKey()); // remove from map before changing the key
        entry.getKey().add(groupToAdd2);
        entry.getValue().add(groupToAdd);
        map.put(entry.getKey(), entry.getValue());
}

答案 2 :(得分:0)

在Map中,最好保持密钥对象不可变。 当一个人更改HashMap中的密钥对象,并且新的hashCode不同时,地图就会损坏。

所以你必须删除旧的密钥对象并插入新的密钥对象。

适合您的示例的数据结构将是(group,datum)树,您可以在其中扩展叶子的路径。

tree -> (a, 1)
            +--> (x, 24)
            +--> (b, 2)
                      +--> (c, 3)

只考虑最后一页的所有路径。

不可否认,还有一点工作要做。