2015-02-22 4 views
1

У меня есть это назначение, чтобы создать метод равных для дважды связанного списка. До сих пор я получил код, который я разместил ниже. Он проходит некоторые тесты, но не все. Ошибки имеют то же ожидаемое значение, что и фактическое значение, но я все еще получаю некоторые AssertionErrors.equals метод для DoublyLinkedList

Ive был messing и пытается изменить вещи в течение довольно долгого времени, но я наклоняю, кажется, чтобы понять это самостоятельно. Я также не могу найти хорошие примеры в Интернете. Я попытался использовать Eclipse для генерации метода equals, но это тоже не проходит все тесты.

Я знаю, что вы не дадите бесплатные ответы здесь, но может кто-то может указать на ошибку в коде?

/** 
    * This method should return true iff the values of this list 
    * and that are identical and in the same order. 
    * @param that list to compare this to. 
    * @return true iff the values are identical and in the same order 
    */ 
    public boolean equals(Object that) { 
     if (that == null) 
     return false; 
     if (!(that instanceof DoublyLinkedList)) 
    return false; 

    DoublyLinkedList<E> other = (DoublyLinkedList<E>) that; 
    if (header == null&&other.header != null) 
      return false; 
     if (trailer == null&&other.trailer != null) 
      return false;   

    while (header.getNext() != trailer){ 
     if (!(header.equals(other.header))){ 
       return false; 
     } 
       header = header.getNext(); 
       other.header = other.header.getNext(); 
    } 
     return true; 
    } 

Редактировать, по запросу неудавшиеся тесты ан DLL класса:

public static class DoublyLinkedList<E> { 
    private Node<E> header; 
    private Node<E> trailer; 

    /** 
    * Constructor that creates an empty DLL 
    */ 
    public DoublyLinkedList() { 
     this.header = new Node<>(null, null, null); 
     this.trailer = new Node<>(null, header, null); 
     this.header.setNext(trailer); 
    } 

    /** 
    * @return if the list is empty. 
    */ 
    public boolean isEmpty() { 
     return this.header.getNext() == this.trailer; 
    } 

    /** 
    * @return the first element of the list. 
    */ 
    public E getFirst() { 
     if (isEmpty()) return null; 
     return this.header.getNext().getElement(); 
    } 

    /** 
    * @return the last element of the list. 
    */ 
    public E getLast() { 
     if (isEmpty()) return null; 
     return this.trailer.getPrevious().getElement(); 
    } 


    /** 
    * Adds a new Node to the beginning of the list, 
    * containing the specified value. 
    * @param value for the new first node to hold. 
    */ 
    public void addFirst(E element) { 
     Node<E> newNode = new Node<>(element, header, header.getNext()); 
     header.getNext().setPrevious(newNode); 
     header.setNext(newNode); 
    } 

    /** 
    * This method should return true iff the values of this list 
    * and that are identical and in the same order. 
    * @param that list to compare this to. 
    * @return true iff the values are identical and in the same order 
    */ 
    public boolean equals(Object that) { 
     if (that == null) 
     return false; 
     if (!(that instanceof DoublyLinkedList)) 
    return false; 

    DoublyLinkedList<E> other = (DoublyLinkedList<E>) that; 
    if (header == null&&other.header != null) 
      return false; 
     if (trailer == null&&other.trailer != null) 
      return false;   

    while (header.getNext() != trailer){ 
     if (!(header.equals(other.header))){ 
       return false; 
     } 
       header = header.getNext(); 
       other.header = other.header.getNext(); 
    } 
     return true; 
    } 


    /** 
    * Simple toString for testing purposes. Please note that solutions that use the 
    * .toString() to implement the .equals() method will be rejected. 
    */ 
    public String toString() { 
     StringBuilder sb = new StringBuilder(); 
     sb.append("DoublyLinkedList<"); 

     Node<E> finger = header.getNext(); 
     while (finger != trailer) { 
      sb.append(finger.toString()); 
      if (finger.getNext() != trailer) { 
       sb.append("-"); 
      } 
      finger = finger.getNext(); 
     } 

     sb.append(">"); 
     return sb.toString(); 
    } 
} 

И тесты:

@Test 
    public void testEqualsCopy() { 
     Solution.DoublyLinkedList<Integer> dll1 = createDLL(2); 
     Solution.DoublyLinkedList<Integer> dll2 = createDLL(2); 
     assertEquals(dll1, dll2); 
    } 
     @Test 
    // Both lists contain only the entry 42. 
    public void testTwoEqualLists() { 
     Solution.DoublyLinkedList<Integer> dll1 = new Solution.DoublyLinkedList<>(); 
     Solution.DoublyLinkedList<Integer> dll2 = new Solution.DoublyLinkedList<>(); 
     dll1.addFirst(42); 
     dll2.addFirst(42); 
     assertEquals(dll1, dll2); 
    } 

и ошибки:

testEqualsCopy(UTest) failed: 'java.lang.AssertionError: expected: Solution$DoublyLinkedList<DoublyLinkedList<1-0>> but was: Solution$DoublyLinkedList<DoublyLinkedList<1-0>>' 
testTwoEqualLists(UTest) failed: 'java.lang.AssertionError: expected: Solution$DoublyLinkedList<DoublyLinkedList<42>> but was: Solution$DoublyLinkedList<DoublyLinkedList<42>>' 
+1

Ну сформулировал вопрос. Можете ли вы предоставить тесты, которые терпят неудачу? Также укажите код для класса DoublyLinkedList. – CKing

+1

«Я знаю, что вы не дадите бесплатные ответы здесь». Кто-то обвинил вас в ответе? – SMA

+1

@SMA Он ​​не имел в виду деньги, но время, проведенное с ответом на вопрос. – CKing

ответ

1

Так, есть довольно разрыв между тем, что я думаю, список должен выглядеть и что у вас есть, я хотел бы добавить свою примерную реализацию вместо этого. Это устраняет манекен заголовок и прицеп узлов, которые ИМХО не требуются вообще.

public class DoublyLinkedList<E> { 

    private Node<E> header; 
    private Node<E> trailer; 

    /** 
    * @return if the list is empty. 
    */ 
    public boolean isEmpty() { 
     return header == null; 
    } 

    /** 
    * @return the first element of the list. 
    */ 
    public E getFirst() { 
     return header != null ? header.getElement() : null; 
    } 

    /** 
    * @return the last element of the list. 
    */ 
    public E getLast() { 
     return trailer != null ? trailer.getElement() : null; 
    } 

    /** 
    * Adds a new Node to the beginning of the list, 
    * containing the specified value. 
    * @param value for the new first node to hold. 
    */ 
    public void addFirst(E element) { 
     Node<E> newNode = new Node<E>(element, null, header); 
     header = newNode; 
     if (trailer == null) { 
      trailer = newNode; 
     } 
    } 

    /** 
    * This method should return true if the values of this list and that are 
    * identical and in the same order. 
    * 
    * @param that 
    *   list to compare this to. 
    * @return true if the values are identical and in the same order 
    */ 
    @SuppressWarnings("unchecked") 
    public boolean equals(Object that) { 
     if (!(that instanceof DoublyLinkedList)) 
      return false; 

     DoublyLinkedList<E> other = (DoublyLinkedList<E>) that; 

     // if lists are empty 
     if (header == null) { 
      return other.header == null ? true : false; 
     } 

     if (!header.equals(other.header)) 
      return false; 

     // Just one element 
     if (header == trailer) { 
      return true; 
     } 

     if (!trailer.equals(other.trailer)) 
      return false; 

     Node<E> thisNode = header; 
     Node<E> otherNode = other.header; 

     while (thisNode.getNext() != trailer) { 
      thisNode = thisNode.getNext(); 
      otherNode = otherNode.getNext(); 
      if (!(thisNode.equals(otherNode))) { 
       return false; 
      } 
     } 
     return true; 
    } 


    /** 
    * Simple toString for testing purposes. Please note that solutions that use the 
    * .toString() to implement the .equals() method will be rejected. 
    */ 
    public String toString() { 
     StringBuilder sb = new StringBuilder(); 
     sb.append("DoublyLinkedList<"); 

     Node<E> finger = header; 
     while (finger != null) { 
      sb.append(finger.toString()); 
      if (finger.getNext() != null) { 
       sb.append("-"); 
      } 
      finger = finger.getNext(); 
     } 

     sb.append(">"); 
     return sb.toString(); 
    } 
} 

Вот что мой класс Node выглядит. Здесь не так много изменений.

public class Node<E> { 

    private E element; 
    private Node<E> previous; 
    private Node<E> next; 

    public Node<E> getPrevious() { 
     return previous; 
    } 

    public Node<E> getNext() { 
     return next; 
    } 

    public E getElement() { 
     return element; 
    } 

    public Node(E element, Node<E> previous, Node<E> next) { 
     this.element = element; 
     this.previous = previous; 
     this.next = next; 
    } 

    @Override 
    @SuppressWarnings("unchecked") 
    public boolean equals(Object that) { 
     if (!(that instanceof Node)) { 
      return false; 
     } 
     Node<E> other = (Node<E>) that; 
     if (element == null) { 
      return other.element == null ? true : false; 
     } 
     return element.equals(other.element); 
    } 

    @Override 
    public String toString() { 
     return element.toString(); 
    } 
} 

Вот код, который я использовал для проверки моей реализации.

DoublyLinkedList<Integer> dll1 = new DoublyLinkedList<Integer>(); 
dll1.addFirst(100); 
dll1.addFirst(200); 

DoublyLinkedList<Integer> dll2 = new DoublyLinkedList<Integer>(); 
dll2.addFirst(100); 
dll2.addFirst(200); 

DoublyLinkedList<Integer> dll3 = new DoublyLinkedList<Integer>(); 
dll3.addFirst(42); 

DoublyLinkedList<String> blankList1 = new DoublyLinkedList<String>(); 
DoublyLinkedList<String> blankList2 = new DoublyLinkedList<String>(); 

if (blankList1.equals(blankList2)) { 
    System.out.println(blankList1 + " = " + blankList2); 
} 

if (!dll1.equals(dll3)) { 
    System.out.println(dll1 + " != " + dll3); 
} 

if (dll1.equals(dll2)) { 
    System.out.println(dll1 + " = " + dll2); 
} 

Выход:

DoublyLinkedList<> = DoublyLinkedList<> 
DoublyLinkedList<200-100> != DoublyLinkedList<42> 
DoublyLinkedList<200-100> = DoublyLinkedList<200-100> 
+0

Прежде всего, спасибо за подробный ответ, но поскольку я использую equals (Object other) вместо equals (DoublyLinkedList other), мне все равно нужно использовать с помощью DoublyLinkedList other = (DoublyLinkedList ), что; или изменить параметр. Правильно? Также я попытался переписать все равные с помощью ваших шагов, но все еще не прошел тесты. – Zouter

+0

А, это был грубый недосмотр с моей стороны. Исправленный. –

+0

На самом деле, есть много пробелов между тем, что, как я думал, будет выглядеть ваш двойной список. Например, даже ваш пустой связанный список содержит два узла, для которых ИМХО не требуется. Только две ссылки на Node выполнили бы эту работу. –

Смежные вопросы