深入复制Java中的泛型

时间:2017-03-19 02:09:29

标签: java generics deep-copy

我有一个编程任务,用Java创建一个通用堆栈,我需要制作一个newNode T的深层副本。我不知道如何创建一个深度复制的方法可以访问它自己并输出i&# 39;深刻的副本。到目前为止,我有这个:

public class Stack<T>
{ 

    private T[] data;
   private int top;
   private int size;
   public Stack( )
   {  top = -1;
      size = 100;
      data = (T[])new Object[100];
   }
   public Stack(int n)
   {  top = -1;
      size = n;
      data = (T[])new Object[n];
   }
   public boolean push(T newNode)
   {  if(top == size-1)
           return false;  // ** overflow error **
       else
       {  top = top +1;
          data[top] = newNode.deepCopy();
          return true;  // push operation successful
       }
   }
   public T pop( )
   {  int topLocation;
       if(top == -1)
           return null;  // ** underflow error **
       else
       {  topLocation = top;
           top = top -1;
           return data[topLocation];
       }
   }
   public void showAll( )
   {  for(int i = top; i >= 0; i--)
         System.out.println(data[i].toString());
   }


}

如何制作newNode的深层副本。我很确定我需要一个接口用于该方法,但过去我失去了。

3 个答案:

答案 0 :(得分:0)

也许最通用和最直接的解决方案是要求使用代码在构造时提供深度复制例程:

public class Stack<T> {
  ...
  private final Function<T, T> elementCopier;
  public Stack<T>(Function<T, T> elementCopier) {
     // make sure thy are not passing you a null copier:
     this.elementCopier = Objects.requiresNonNull(elementCopier);
     ...
  }
  ...
  public boolean push(T element) {
     ...
     data[top] = elementCopier.apply(element);
     ...
  }
  ...
}

因此,例如对于一个可克隆的类类型,其中.clone()实际上是一个deepCopy,用户代码就像:

Stack<MyElemClz> stack = new Stack<>(x -> x.clone());
// or:
Stack<MyElemClz> stack = new Stack<>(MyElemClz::clone);
...
MyElemClaz elem = ...;
...
stack.push(elem);

如果类型是像String这样的常量简单对象,则不需要克隆,在这种情况下,用户会将标识lambda x -> x表示为 复印机:

Stack<String> stack = new Stack<>(x -> x)

如果用户坚持制作副本,即使该类是常量,也可以强制它:

Stack<String> stack = new Stack<>(x -> new String(x))
// or
Stack<String> stack = new Stack<>(String::new)

答案 1 :(得分:0)

如果您想要使用界面,或者您不喜欢Valentin的方法,则可以执行以下操作:

interface Copiable<T> {
    T deepCopy();
}

public class Stack<T extends Copiable<T>> {
...
}

,然后对您放入堆栈的对象(即

)实施deepCopy方法
class A implements Copiable<A> {
  @Override
  public A deepCopy() {
    // ... your copy code here
  }
}

Stack<A> stack = new Stack<>();

答案 2 :(得分:0)

一个人可以使用ObjectOutputStream/ObjectInputStream制作一个深层副本。 这样,就不会存储对象(对可变字段的引用),而是将序列化的字节存储在堆栈中。

继续。

ObjectOutputStream进行深层复制。