我想创建链接哈希映射的副本,然后我想删除所有值(从列表中)而不是第一个条目。这是我得到的:
LinkedHashMap<String, List<Value>> facetsInCategoriesCopy = new LinkedHashMap<>(facetsInCategories);
if (!facets.equals("something")) {
for (List<Value> value : facetsInCategoriesCopy.values()) {
if (value.size() > 1) {
int nbrOfElements = value.size();
for (int i = nbrOfElements-1; i > 0; i--) {
value.remove(i);
}
}
}
}
在此操作之后,事实证明facetsInCategories也被修改。为什么?以及如何解决这个问题? 任何帮助将不胜感激。
答案 0 :(得分:1)
我没有50个声誉来添加评论。请参阅此回答Assigning Hashmap to Hashmap
基本上,您用于制作新地图的复制构造函数引用了可变对象,即facetsInCategories
,并且在您更新facetsInCategoriesCopy
地图时也会对其进行更新。
解决方案是改为执行深层复制。我在下面添加了测试代码,我使用的是String
而不是Value
//Test for https://stackoverflow.com/questions/27324315/
public static void testStackO_Q_27324315() {
Map<String, List<String>> facetsInCategories = new LinkedHashMap<String, List<String>>();
String[] values = new String[]{"Test1", "Test2", "Test3"};
List<String> valuesList = new ArrayList<String>(Arrays.asList(values));
facetsInCategories.put("Test", valuesList);
Map temp = Collections.unmodifiableMap(facetsInCategories);
LinkedHashMap<String, List<String>> facetsInCategoriesCopy = (LinkedHashMap<String, List<String>>)deepCopy(temp);
String facets = "test_me";
if (!facets.equals("something")) {
for (List<String> value : facetsInCategoriesCopy.values()) {
if (value.size() > 1) {
int nbrOfElements = value.size();
for (int i = nbrOfElements-1; i > 0; i--) {
value.remove(i);
}
}
}
}
System.out.println(facetsInCategories);
System.out.println(facetsInCategoriesCopy);
}
public static <K1, K2, V> Map<K1, List<V>> deepCopy(
Map<K1, List<V>> original){
Map<K1, List<V>> copy = new LinkedHashMap<K1, List<V>>();
for(Map.Entry<K1, List<V>> entry : original.entrySet()){
copy.put(entry.getKey(), new ArrayList<V>(entry.getValue()));
}
return copy;
}