廣告

2017年4月21日 星期五

[java] Deep clone

使用原因

  Map a = new HashMap();
  Map b = new HashMap();

  a.put("1","a");
  a.put("2", "b");

  b.remove("1");
//此時 a的"1"也會被rm掉



usage:
Map> tempMap = DeepClone.deepClone(conditionMap);


package com.ws.util;

import java.lang.reflect.Array;
import java.util.*;

/**
* Created by 1409035 lewisli on 2016/11/30.
*/
public final class DeepClone {

  private DeepClone(){}

  @SuppressWarnings("unchecked")
  public static  X deepClone(final X input) {
  if (input == null) {
  return input;
  } else if (input instanceof Map) {
  return (X) deepCloneMap((Map) input);
  } else if (input instanceof Collection) {
  return (X) deepCloneCollection((Collection) input);
  } else if (input instanceof Object[]) {
  return (X) deepCloneObjectArray((Object[]) input);
  } else if (input.getClass().isArray()) {
  return (X) clonePrimitiveArray((Object) input);
  }

  return input;
  }

  @SuppressWarnings("unchecked")
  private static Object clonePrimitiveArray(final Object input) {
  final int length = Array.getLength(input);
  final Object copy = Array.newInstance(input.getClass().getComponentType(), length);
  // deep clone not necessary, primitives are immutable
  System.arraycopy(input, 0, copy, 0, length);
  return copy;
  }

  @SuppressWarnings("unchecked")
  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;
  }

  @SuppressWarnings("unchecked")
  private static  Collection deepCloneCollection(final Collection input) {
  Collection clone;
  // this is of course far from comprehensive. extend this as needed
  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;
  }

  @SuppressWarnings("unchecked")
  private static  Map deepCloneMap(final Map map) {
  Map clone;
  // this is of course far from comprehensive. extend this as needed
  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;
  }
}


ref: http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value