简体   繁体   English

Java 中 HashMap 的深拷贝

[英]Deep Copy of HashMap in Java

I am having difficulty making a deep copy of a HashMap.我很难制作 HashMap 的深层副本。 I tried the code below from How to copy HashMap (not shallow copy) in Java , but List at List.copyOf is giving me an error (Cannot resolve symbol 'List') and I'm not sure what to replace it with.我从How to copy HashMap (not shallow copy) in Java尝试了下面的代码,但是 List.copyOf 的 List 给了我一个错误(无法解析符号'List'),我不知道用什么替换它。 If there is any other way to make a deep copy of HashMap, I would love to hear.如果有任何其他方法可以制作 HashMap 的深层副本,我很想听听。

private HashMap<Character, ArrayList<int[]>> board;

public Vertex(HashMap<Character, ArrayList<int[]>> inputboard) {
        board = new HashMap<>();
        this.board = copy(inputboard);
}

public HashMap<Character, ArrayList<int[]>> copy (HashMap<Character, ArrayList<int[]>> original) {  
        HashMap<Character, ArrayList<int[]>> copy = original.entrySet().stream()
                .collect(Collectors.toMap(e -> e.getKey(), e -> List.copyOf(e.getValue())));
        return copy;
}

Before I used the above code, I also tried this from How to copy HashMap (not shallow copy) in Java but it did not make a deep copy在我使用上面的代码之前,我也尝试过如何在 Java 中复制 HashMap(非浅拷贝),但它没有进行深拷贝

private HashMap<Character, ArrayList<int[]>> board;

public Vertex(HashMap<Character, ArrayList<int[]>> inputboard) {
        board = new HashMap<>();
        this.board = copy(inputboard);
}

public HashMap<Character, ArrayList<int[]>> copy (HashMap<Character, ArrayList<int[]>> original) {
       HashMap<Character, ArrayList<int[]>> copy = new HashMap<>();
       for (Map.Entry<Character, ArrayList<int[]>> entry : original.entrySet()) {
            copy.put(entry.getKey(), new ArrayList<>(entry.getValue()));
       }
       return copy;
}

Both ways you showed doesn't copy the int[] , ie not copying as deep as you want.您展示的两种方式都不会复制int[] ,即没有复制到您想要的深度。

The first way actually returns a Map<Character, List<int[]>> rather than the HashMap<Character, ArrayList<int[]>> you want.第一种方法实际上返回Map<Character, List<int[]>>而不是您想要的HashMap<Character, ArrayList<int[]>> I would recommend that you program to interfaces and change your method to return a Map<Character, List<int[]>> instead, then you can use streams like this:我建议您对接口进行编程并更改方法以返回Map<Character, List<int[]>> ,然后您可以使用这样的流:

public Map<Character, List<int[]>> copy (HashMap<Character, ArrayList<int[]>> original) {
    Map<Character, List<int[]>> copy = original.entrySet().stream()
        .collect(Collectors.toMap(
            Entry::getKey,
            e -> e.getValue().stream().map(x -> Arrays.copyOf(x, x.length)).collect(Collectors.toList())
        ));
    return copy;
}

If you really don't want to change the return type, you'd have to pass more arguments to specify the concrete types you want:如果您真的不想更改返回类型,则必须传递更多 arguments 来指定您想要的具体类型:

public HashMap<Character, ArrayList<int[]>> copy (HashMap<Character, ArrayList<int[]>> original) {
    HashMap<Character, ArrayList<int[]>> copy = original.entrySet().stream()
        .collect(Collectors.toMap(
            Entry::getKey,
            e -> e.getValue().stream().map(x -> Arrays.copyOf(x, x.length)).collect(Collectors.toCollection(ArrayList::new)),
            (x, y) -> x,
            HashMap::new
        ));
    return copy;
}

Otherwise, you can use the traditional for loops:否则,您可以使用传统的 for 循环:

public HashMap<Character, ArrayList<int[]>> copy (HashMap<Character, ArrayList<int[]>> original) {
    HashMap<Character, ArrayList<int[]>> copy = new HashMap<>();
    for (Map.Entry<Character, ArrayList<int[]>> entry : original.entrySet()) {
        ArrayList<int[]> listCopy = new ArrayList<>();
        for (int[] array: entry.getValue()) {
            listCopy.add(Arrays.copyOf(array, array.length));
        }
        copy.put(entry.getKey(), listCopy);
    }
    return copy;
}

Notice that in all three code snippets, I have used Arrays.copyOf to copy the int[] .请注意,在所有三个代码片段中,我都使用Arrays.copyOf来复制int[]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM