我正在开展一个项目,该项目涉及一些工作的数据集的微小组合和关联,并且已经停留了一段时间。
我有一组数据,类似于项目中的其他数据组。我有一个组名的数组列表。我将这些类似的组与其他数据集进行比较,描述类似的事情。 (一组组,与其自己的集合中的其他组类似)。
我一直试图通过使用:
来解决这个问题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或类似的结构吗?
答案 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);
更改键,但地图的键必须是有效的不可变的:
交换行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)
只考虑最后一页的所有路径。
不可否认,还有一点工作要做。