Java:LinkedHashMap重叠自己

时间:2014-12-05 20:40:21

标签: java linkedhashmap

我想创建链接哈希映射的副本,然后我想删除所有值(从列表中)而不是第一个条目。这是我得到的:

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也被修改。为什么?以及如何解决这个问题? 任何帮助将不胜感激。

1 个答案:

答案 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;
  }