2

I have a programming assignment to make a generic stack in Java and I need to make a deep copy of newNode T. I don't know how to make a method deep Copy that can access its self and output i'`s deep copy. So far, I have this:

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());
   }


}

How can I make the deep copy of newNode. I'm pretty sure I need an interface for the method but past that I`m lost.

icedwater
  • 4,701
  • 3
  • 35
  • 50
Epics5150
  • 21
  • 3
  • Welcome to SO. See: http://stackoverflow.com/questions/64036/how-do-you-make-a-deep-copy-of-an-object-in-java . Is there any additional information about `T` ? Does it implement the `clonable` interface ? – c0der Mar 19 '17 at 05:40
  • @c0der: Whether it implements `Cloneable` or not is irrelevant. `Cloneable` does not provide a public cloning method; it serves a different purpose. – newacct Apr 01 '17 at 01:53
  • @newacct , Still as pointed by @c0der , some more info about the actual `T` might helpful , cause when you are trying to deep copy references that have other references it ends to a bad loop....... – AntJavaDev Sep 19 '18 at 08:33

3 Answers3

0

Perhaps the most general and straight forward solution would consist in asking the using code to provide the deep-copying routine at construction:

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);
     ...
  }
  ...
}

So for example for a cloneable class type where .clone() is in fact a deepCopy the user code would be like:

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

If the type is an constant simple object like and String there is no need for clonning, in that case the user would indicate identity lambda x -> x as the copier:

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

If the user insists in making a copy even when the class is a constant you can force it:

Stack<String> stack = new Stack<>(x -> new String(x))
// or
Stack<String> stack = new Stack<>(String::new)
Valentin Ruano
  • 2,726
  • 19
  • 29
0

If you want to go with an interface, or you don't like Valentin's approach, you could do this:

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

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

and then implement the deepCopy method to objects that you put in your stack, i.e.

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

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

etc.

memo
  • 1,868
  • 11
  • 19
0

One can use an ObjectOutputStream/ObjectInputStream to make a deep copy. One would then not store an Object (a reference to changeable fields), but the serialized bytes in the stack.

On to it.

An ObjectOutputStream does a deep copy.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138