Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
272 views
in Technique[技术] by (71.8m points)

java - 如何为LinkedList的浅/深副本执行Junit(how to do Junit for shallow/deep copy of LinkedList)

hello there i did the deep copy and the shallow copy is suggested by the user AndyMan and now i did the JUnit and im having a slight problem making those tests:

(你好,我做了深层副本,浅层副本是由用户AndyMan建议的,现在我做了JUnit,即时通讯在进行这些测试时有一个小问题:)

1.deep copy method

(1.深复制方法)

   public ListNode<E> deep_clone() {
           first = deep_clone(first);
           ListNode<E> copy = new ListNode<>(first);
     return copy;
    } 

    private static Node deep_clone(Node head) {
        if (head == null) {
            return null;
        }

        Node temp = new Node(head.getData());
        temp.setNext(deep_clone(head.getNext()));

        return temp;
    }

Edit

(编辑)

many thanks for AndyMan for suggesting this shallow copy method:

(非常感谢AndyMan建议使用这种浅拷贝方法:)

private static Node shallow_clone(Node head) {
   if (head == null)
      return null;

   Node temp = new Node(head.getData());
   temp.setNext(head.getNext());  // Just copy the reference

return temp;
}

but one question though how to Junit both the deep and shallow copy methods?

(但尽管一个问题如何Junit深深浅浅的复制方法两者兼而有之?)

i did the following and i got a failed Junit test:

(我执行了以下操作,但Junit测试失败:)

@Test
public void test_shallow_clone(){
    ListNode<Integer> list =new ListNode<>();
    for (int i = 0; i < 10; i++)
        list.insert(i);

    ListNode<Integer>cloned =list.shallow_clone();
    //assertSame(cloned,list); //failed i dont know why
    //assertEquals(cloned, list);//Even though its shallow copy i get that they are  not equal!
    assertSame(list.getFirst(), cloned.getFirst());
    assertTrue(cloned.equals(list));
}

and the test for the deep copy:

(以及深层副本的测试:)

@Test
public void test_depp_clone(){
    ListNode<Integer> list =new ListNode<>();
    for (int i = 0; i < 10; i++)
        list.insert(i);

    ListNode<Integer>cloned =list.depp_clone();

    assertSame(cloned.getFirst(),list.getFirst());//check for same val..
    //assertEquals(cloned, list);//this make the test fail..
    assertFalse(cloned.equals(list));//okay the are not equal lists this means its deep copy...no implemented equal method :)
}

class ListNode

(ListNode类)

public class ListNode<E> implements Iterable<E>{

private Node<E> first;
//private Node<E> last;

public ListNode() {
    first = null;
    //last = null;
}

public ListNode(Node head) {
    this.first = head;
    //this.last = this.first;
}

public ListNode(E data) {
    Node head = new Node(data);
    this.first = head;
    //this.last = this.first;
}

@Override
public Iterator<E> iterator() {
    return new LL_Iterator<>(first);
}

private static class Node<E> {

    private E data;
    private Node next;

    public Node() {
        this.data = null;
        this.next = null;
    }

    public Node(E data) {
        this.data = data;
        next = null;
    }

    public Node(E data, Node next) {
        this.data = data;
        this.next = null;
    }

    public E getData() {
        return data;
    }

    public void setData(E val) {
        this.data = val;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }

    @Override
    public String toString() {
        return "Node{" + "data=" + data + ", next=" + next + '}';
    }

}

private static class LL_Iterator<E> implements Iterator<E> {

    private Node<E> curr;//we have to specify the E here because if we dont we have to cast the curr.getData()

    public LL_Iterator(Node head) {
        curr = head;
    }

    @Override
    public boolean hasNext() {
        return curr != null;
    }

    @Override
    public E next() {
        if (hasNext()) {
            E data = curr.getData();
            curr = curr.getNext();
            return data;
        }
        return null;
    }

}

public E getFirst(){
    if(first==null)
        return null;

    return first.getData();
}

public boolean addFirst (E data) {
    if(data==null)
        return false;

    Node t= new Node (data);
    t.setNext(first);
    first=t;
    return true;
}

public E getLast() {
    if (first==null)
        return null;
    return getLast(first).getData();
}

private static<E> Node<E> getLast(Node<E> head) {
    if (head == null) {
        return null;
    }

    Node temp = head;
    if (temp.getNext() != null) {
        temp = getLast(temp.getNext());
    }

    return temp;
}

//insertion....Wie setLast
public boolean insert(E data) {
    if(data==null)
        return false;

    first = insert(first, data);
    //last = getLast();
    return true;
}

private static <E> Node insert(Node head, E data) {
    if (head == null) {
        return new Node(data);
    } else {
        head.setNext(insert(head.getNext(), data));
    }
    return head;
}

public void printList(){
    LL_Iterator it= new LL_Iterator(first);
    printUsingIterator(it,it.next());

}

private static<E> void printUsingIterator (LL_Iterator it, E data){

    //VERDAMMT MAL RHEINFOLGE DER ANWEISUNGEN MACHT UNTERSCHIED
    System.out.print(data+"->");

    if (!it.hasNext()) {
        System.out.print(it.next()+"
");//THIS WILL PRINT NULL!!!
        return;
    }
    printUsingIterator(it,it.next());
}

public int size() {
    return size(first);
}

private static int size(Node head) {
    if (head == null) {
        return 0;
    } else {
        return 1 + size(head.getNext());
    }
}

public boolean contains(E data) {
    return contains(first, data);
}

public static <E> boolean contains(Node head, E data) {
    if (head == null || data == null) {
        return false;
    }
    if (head.getData().equals(data)) {
        return true;
    }
    return contains(head.getNext(), data);
}

public int countIf(E t) {
    return countIf(first, t);
}

private static <E> int countIf(Node head, E t) {
    if (head == null ||t ==null) {
        return 0;
    }
    if (head.getData().equals(t)) {
        return 1 + countIf(head.getNext(), t);
    }

    return countIf(head.getNext(), t);
}


//TODO: WHY IM GETTING HERE AN OVERRIDE REQUEST FROM THE COMPILER??
//answer because im overriding the damn clone() of the list class which is shallow clone
public ListNode<E> depp_clone() {
    first = depp_clone(first);
    ListNode<E> copy = new ListNode<>(first);
    return copy;
}

private static Node depp_clone(Node head) {
    if (head == null) {
        return null;
    }

    Node temp = new Node(head.getData());
    temp.setNext(depp_clone(head.getNext()));

    return temp;
}

public ListNode shallow_clone (){
    ListNode<E> cloned=new ListNode<>(shallow_clone(first));
    return cloned;
}
private static Node shallow_clone(Node head) {
    if (head == null)
        return null;

    Node temp = new Node(head.getData());
    temp.setNext(head.getNext());  // Just copy the reference

    return temp;
}
  ask by studentaccount4 translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Say head points to node0 which points to node1: head = node0 => node1

(说head指向node0,node0指向node1:head = node0 => node1)

In a deep copy, create two new nodes 7 and 8: deepCopy = node7 => node6

(在深度复制中,创建两个新的节点7和8:deepCopy = node7 => node6)

In a shallow copy, create one new node 7 and copy reference to original node: shallowCopy = node7 => node1

(在浅表副本中,创建一个新节点7并将引用复制到原始节点:shallowCopy = node7 => node1)

private static Node shallow_clone(Node head) {
if (head == null) {
    return null;
}

Node temp = new Node(head.getData());
temp.setNext(head.getNext());  // Just copy the reference

return temp;

}

(})

If the original node1 is changed, it will affect both the original and the shallow copy.

(如果更改了原始节点1,则将同时影响原始副本和浅副本。)

it will not affect the deep copy.

(它不会影响深层副本。)

Now for the terminology.

(现在来看术语。)

What has been described is how to deep copy or shallow copy a node.

(已经描述了如何深度复制或浅复制节点。)

It does not really make sense to shallow copy a linked list , because you are really just shallow coping a single node.

(浅表复制链表并没有什么意义 ,因为您实际上只是浅表一个节点。)

Of course you can deep copy the list.

(当然,您可以深度复制列表。)

If it were an array, rather than a linked list, then you could shallow or deep copy.

(如果它是一个数组,而不是一个链表,则可以进行浅拷贝或深拷贝。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...