Copying a HashMap in Java

前端 未结 11 1060
灰色年华
灰色年华 2020-11-29 22:02

I am trying to keep a temporary container of a class that contains member :

HashMap myobjectHashMap

A class called my

11条回答
  •  心在旅途
    2020-11-29 22:25

    If we want to copy an object in Java, there are two possibilities that we need to consider: a shallow copy and a deep copy.

    The shallow copy is the approach when we only copy field values. Therefore, the copy might be dependent on the original object. In the deep copy approach, we make sure that all the objects in the tree are deeply copied, so the copy is not dependent on any earlier existing object that might ever change.

    This question is the perfect definition for the application of the deep copy approach.

    First, if you have a simple HashMap> map then we just create a workaround like this. Creating a new instance of the List.

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

    This one uses Stream.collect() method to create the clone map, but uses the same idea as the previous method.

    public static  Map> deepCopyStreamWorkAround(Map> original)
    {
        return original
                .entrySet()
                .stream()
                .collect(Collectors.toMap(Map.Entry::getKey, valueMapper -> new ArrayList<>(valueMapper.getValue())));
    }   
    

    But, if the instances inside T are also mutable objects we have a big problem. In this case a real deep copy is an alternative that solves this problem. Its advantage is that at least each mutable object in the object graph is recursively copied. Since the copy is not dependent on any mutable object that was created earlier, it won’t get modified by accident like we saw with the shallow copy.

    To solve that this deep copy implementations will do the work.

    public class DeepClone
    {
        public static void main(String[] args)
        {
            Map itemMap = Stream.of(
                    entry(0L, new Item(2558584)),
                    entry(1L, new Item(254243232)),
                    entry(2L, new Item(986786)),
                    entry(3L, new Item(672542)),
                    entry(4L, new Item(4846)),
                    entry(5L, new Item(76867467)),
                    entry(6L, new Item(986786)),
                    entry(7L, new Item(7969768)),
                    entry(8L, new Item(68868486)),
                    entry(9L, new Item(923)),
                    entry(10L, new Item(986786)),
                    entry(11L, new Item(549768)),
                    entry(12L, new Item(796168)),
                    entry(13L, new Item(868421)),
                    entry(14L, new Item(923)),
                    entry(15L, new Item(986786)),
                    entry(16L, new Item(549768)),
                    entry(17L, new Item(4846)),
                    entry(18L, new Item(4846)),
                    entry(19L, new Item(76867467)),
                    entry(20L, new Item(986786)),
                    entry(21L, new Item(7969768)),
                    entry(22L, new Item(923)),
                    entry(23L, new Item(4846)),
                    entry(24L, new Item(986786)),
                    entry(25L, new Item(549768))
            ).collect(entriesToMap());
    
    
            Map clone = DeepClone.deepClone(itemMap);
            clone.remove(1L);
            clone.remove(2L);
    
            System.out.println(itemMap);
            System.out.println(clone);
        }
    
        private DeepClone() {}
    
        public static  T deepClone(final T input)
        {
            if (input == null) return null;
    
            if (input instanceof Map) {
                return (T) deepCloneMap((Map) input);
            } else if (input instanceof Collection) {
                return (T) deepCloneCollection((Collection) input);
            } else if (input instanceof Object[]) {
                return (T) deepCloneObjectArray((Object[]) input);
            } else if (input.getClass().isArray()) {
                return (T) clonePrimitiveArray((Object) input);
            }
    
            return input;
        }
    
        private static Object clonePrimitiveArray(final Object input)
        {
            final int length = Array.getLength(input);
            final Object output = Array.newInstance(input.getClass().getComponentType(), length);
            System.arraycopy(input, 0, output, 0, length);
            return output;
        }
    
        private static  E[] deepCloneObjectArray(final E[] input)
        {
            final E[] clone = (E[]) Array.newInstance(input.getClass().getComponentType(), input.length);
            for (int i = 0; i < input.length; i++) {
                clone[i] = deepClone(input[i]);
            }
    
            return clone;
        }
    
        private static  Collection deepCloneCollection(final Collection input)
        {
            Collection clone;
            if (input instanceof LinkedList) {
                clone = new LinkedList<>();
            } else if (input instanceof SortedSet) {
                clone = new TreeSet<>();
            } else if (input instanceof Set) {
                clone = new HashSet<>();
            } else {
                clone = new ArrayList<>();
            }
    
            for (E item : input) {
                clone.add(deepClone(item));
            }
    
            return clone;
        }
    
        private static  Map deepCloneMap(final Map map)
        {
            Map clone;
            if (map instanceof LinkedHashMap) {
                clone = new LinkedHashMap<>();
            } else if (map instanceof TreeMap) {
                clone = new TreeMap<>();
            } else {
                clone = new HashMap<>();
            }
    
            for (Map.Entry entry : map.entrySet()) {
                clone.put(deepClone(entry.getKey()), deepClone(entry.getValue()));
            }
    
            return clone;
        }
    }
    

提交回复
热议问题