2017-02-06 20 views
-3

Я пытаюсь создать индивидуальный LinkedList, чтобы лучше понять структуру данных. Я не мог понять, в чем проблема моего класса LinkedList.Почему мой настраиваемый LinkedList не работает?

package numberlist.primitivelist.objectlist; 

public class ObjectLinkedList extends ObjectList implements Copiable { 

Node firstNode; 

/** 
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
* 
* Method: ObjectLinkedList() description:constructor 
* 
* @author Jinyu Wu Date: 2017/2/4 
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
*/ 
public ObjectLinkedList() { 
    firstNode = null; 
} 

/** 
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
* 
* Method: add() description: Insert an item into the list 
* 
* @param index position of the list 
* @param obj the element is going to be inserted 
* @author Jinyu Wu Date: 2017/2/4 
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
*/ 
@Override 
public void add(int index, Object obj) { 
    Node tempNode = firstNode; 
    Node currentNode = new Node(obj); 
    if (index == 0) { 
     firstNode = currentNode; 
     return; 
    } 
    if (index < 0 || index > size()) { 
     System.out.println("add(ObjectLinkedList) index out of bound exception"); 
    } else { 
     for (int i = 1; i <= index; i++) { 
      tempNode = tempNode.getNext(); 
      if (i == index - 1) { 
       if (index != size() - 1) { 
        currentNode.setNext(tempNode.getNext()); 
       } else { 
        currentNode.setNext(null); 
       } 
       tempNode.setNext(currentNode); 
      } 
     } 
    } 

} 

/** 
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
* 
* Method: removeAt() description: remove an item from a position of the 
* list 
* 
* @param index position in the list 
* @author Jinyu Wu Date: 2017/2/4 
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
*/ 
@Override 
public void removeAt(int index) { 
    if (index < 0 || index > size()) { 
     System.out.println("removeAt(ObjectLinkedList) index out of bound exception"); 
    } else { 
     Node tempNode = firstNode; 
     if (index == 0) { 
      firstNode = firstNode.getNext(); 
     } else { 
      for (int i = 1; i <= index; i++) { 
       tempNode = tempNode.getNext(); 
       if (i == index - 1) { 
        if (index != size() - 1) { 
         tempNode.setNext(tempNode.getNext().getNext()); 
        } else { 
         tempNode.setNext(null); 
        } 
       } 
      } 
     } 
    } 

} 

/** 
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
* 
* Method: remove() description: remove a specific item from a position of 
* the list 
* 
* @param obj target object is going to be removed 
* @author Jinyu Wu Date: 2017/2/4 
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
*/ 
@Override 
public void remove(Object obj) { 
    if (size() > 0) { 
     Node tempNode = firstNode; 
     for (int i = 0; i <= size(); i++) { 
      if (tempNode.equals(obj)) { 
       tempNode.setNext(tempNode.getNext().getNext()); 
       break; 
      } 
      if (i < size() - 1) { 
       tempNode = tempNode.getNext(); 
      } 
     } 

     System.out.println("target object is not found inside the linkedList(remove)"); 
    } 
} 

/** 
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
* 
* Method: get() description:get an item from the list 
* 
* @param index position in the list 
* @author Jinyu Wu Date: 2017/2/4 
* @return double ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
*/ 
@Override 
public Object get(int index) { 
    if (index < 0 || index > size()) { 
     System.out.println("get(ObjectLinkedList) index out of bound exception"); 
     return null; 
    } else if (index == 0) { 
     return firstNode; 
    } else { 
     Node tempNode = firstNode; 
     for (int i = 0; i <= index; i++) { 
      if (i == index - 1) { 
       tempNode = tempNode.getNext(); 
       return tempNode; 
      } 
     } 
     System.out.println("objectLinkedList get method nothing found"); 
     return null; 
    } 

} 

/** 
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
* 
* Method: toString() description: print out the content of the list 
* 
* @author Jinyu Wu Date: 2017/2/4 
* @return Integer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
*/ 
@Override 
public String toString() { 
    return "ObjectLinkedList{" + "firstNode=" + firstNode + '}'; 
} 

/** 
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
* 
* Method: find() description:get an item from the list 
* 
* @author Jinyu Wu Date: 2017/2/4 
* @param obj Object is going to be found 
* @return Integer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
*/ 
@Override 
public int find(Object obj) { 
    Node tempNode = firstNode; 
    Node newNode = new Node(obj); 
    if (newNode.equals(firstNode)) { 
     return 0; 
    } else { 
     for (int i = 1; i < size(); i++) { 
      if (tempNode.equals(newNode)) { 
       return i; 
      } 
      tempNode = tempNode.getNext(); 
     } 
     return -1; 
    } 

} 

/** 
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
* 
* Method: size() description:get the size of the list 
* 
* @author Jinyu Wu Date: 2017/2/4 
* @return Integer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
*/ 
@Override 
public int size() { 
    int size = 1; 
    if (firstNode == null) { 
     return 0; 
    } 
    try { 
     for (Node n = firstNode; n.getNext() != null; n = n.getNext()) { 
      size++; 
     } 
     return size; 
    } catch (NullPointerException e) { 
     return size; 
    } 
} 

/** 
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
* 
* Method: deepCopy() description: make a deepCoy for this object 
* 
* @author Jinyu Wu Date: 2017/2/4 
* @return String ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
*/ 
@Override 
public ObjectLinkedList deepCopy() { 
    ObjectLinkedList newList = new ObjectLinkedList(); 
    Node currentNode = firstNode; 

    for (int i = 0; i < size(); i++) { 
     Node newNode = new Node(currentNode.getValue()); 
     newList.add(i, newNode); 
     currentNode = currentNode.getNext(); 
    } 

    return newList; 

} 

}

Вот что делают проверить это с помощью теста Junit

package numberlist.primitivelist.objectlist; 

import org.junit.Before; 
import org.junit.Test; 
import static org.junit.Assert.*; 


public class ObjectLinkedListTest { 

ObjectLinkedList list; 
Money m1, m2; 
Node node1, node2; 

public ObjectLinkedListTest() { 

} 

@Before 
public void setUp() { 
    list = new ObjectLinkedList(); 
    m1 = new Money(5, (byte) 6); 
    node1 = new Node(m1); 
    list.add(0, node1); 

    m2 = new Money(2, (byte) 4); 
    node2 = new Node(m2); 
    list.add(1, node2); 
} 

/** 
* Test of add method, of class ObjectLinkedList. 
*/ 
@Test 
public void testAdd() { 
    assertEquals(list.get(0), node1); 
} 

/** 
* Test of removeAt method, of class ObjectLinkedList. 
*/ 
@Test 
public void testRemoveAt() { 
    list.removeAt(1); 
    assertNull(list.get(1)); 
} 

/** 
* Test of remove method, of class ObjectLinkedList. 
*/ 
@Test 
public void testRemove() { 
    list.remove(m2); 
    assertNull(list.get(1)); 
} 

/** 
* Test of get method, of class ObjectLinkedList. 
*/ 
@Test 
public void testGet() { 
} 

/** 
* Test of toString method, of class ObjectLinkedList. 
*/ 
@Test 
public void testToString() { 
} 

/** 
* Test of find method, of class ObjectLinkedList. 
*/ 
@Test 
public void testFind() { 
    assertEquals(list.find(m1), 0); 
    assertEquals(list.find(m2), 1); 
} 

/** 
* Test of size method, of class ObjectLinkedList. 
*/ 
@Test 
public void testSize() { 
    assertEquals(list.size(), 2); 
} 

/** 
* Test of deepCopy method, of class ObjectLinkedList. 
*/ 
@Test 
public void testDeepCopy() { 

} 

}

Здесь ошибка я получил:

Error here

Мой класс Node:

package numberlist.primitivelist.objectlist; 

public class Node { 

private Node nextNode; 
private Object obj; 

/** 
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
* 
* Method: Node() description: constructor 
* 
* @author Jinyu Wu Date: 2017/2/4 
* @param obj set the value 
*/ 
public Node(Object obj) { 
    this.obj = obj; 
    this.nextNode = null; 
} 

/** 
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
* 
* Method: getValue() description: get the value of object 
* 
* @author Jinyu Wu Date: 2017/2/4 
* @return return the object 
*/ 
public Object getValue() { 
    return this.obj; 
} 

/** 
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
* 
* Method: setValue() description: setValue for the Node 
* 
* @author Jinyu Wu Date: 2017/2/4 
* @param obj return the value 
*/ 
public void setValue(Object obj) { 
    this.obj = obj; 
} 

/** 
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
* 
* Method: getValue() description: get the next value of the currentNode 
* 
* @author Jinyu Wu Date: 2017/2/4 
* @return return next node 
*/ 
public Node getNext() { 
    if (nextNode != null) { 
     return this.nextNode; 
    } else { 
     return null; 
    } 
} 

/** 
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
* 
* Method: setNext() description: set next value for the Node 
* 
* @author Jinyu Wu Date: 2017/2/4 
* @param node set next node 
*/ 
public void setNext(Node node) { 
    this.nextNode = node; 
} 

} 
+0

Как определяется класс 'Node'? – yeputons

+0

Также, как вы пытались отладить код? Каковы ваши выводы, можете ли вы предоставить меньшую часть кода, которая по-прежнему ведет себя странно? – yeputons

ответ

0

Я предполагаю, что это для практики или назначения, java имеет общую реализацию LinkedList уже see the api docs.

Вы можете найти один из многих texts на структуры данных в Java Каталог путешествий, хотя обычно их реализации используют дженерики, а не Object,


Для конкретной задачи можно заметить, что в методе testAdd вы звоните

assertEquals(list.get(0), m1); 

Это сравнение Node к более Money объект, который всегда будет терпеть неудачу.

Вы могли assertEquals(list.get(0).getValue(), m1); Это не будет работать, если вы не измените метод get() вернуть Node, а не Object, как это в настоящее время делает.

У вас возникают аналогичные проблемы с другими тестами, где list.get() возвращает Node, а не данные внутри этого узла.

В качестве альтернативы редактировать метод get() вернуть данные в узле:

... 
    } else if (index == 0) { 
     return firstNode.getValue(); 
    } else { 
    // etc, you have multiple returns in this method 

Edit

Ваш testRemoveAt() выбросит NullPointerException как Получ пытается вызвать tempNode.getNext().getValue(), но у вас есть только один объект Money в списке после теста удаляет второй объект, поэтому getNext() возвращает null.

Edit 2

Это может быть наиболее полезным для вас, чтобы стать более знакомы с отладчиком. Возможно, попробуйте видеоурок для netbeans. Тогда вы расследовать свои исключения. Например, запуск первого теста дает:

java.lang.AssertionError: 
Expected :[email protected] 
Actual :[email protected] 

Это означает, что тест testAdd() не на его призыв к assertEquals(list.get(0), m1);

Что-то здесь отметить, что подпись на assertEquals берет своих ожидаемого значения во-первых, и фактическое значение второе. Поэтому измените эту строку на assertEquals(m1, list.get(0)); и повторите тест.

Теперь выход:

java.lang.AssertionError: 
Expected :[email protected] 
Actual :[email protected] 

Таким образом, тест expectod на Money объект (то будет параметром m1), но list.get(0) возвратил Node объект вместо этого.

Либо тест ожидает неправильной вещи, либо метод get() возвращает неправильную вещь. Я собираюсь предположить, что когда вы вызываете list.get(0), вы действительно хотите получить объект Money, так что это означает, что тест справа, и нам нужно посмотреть на реализацию list.get().

У вас есть:

1. public Object get(int index) { 
2.  if (index < 0 || index > size()) { 
3.   System.out.println("get(ObjectLinkedList) index out of bound exception"); 
4.   return null; 
5.  } else if (index == 0) { 
6.   return firstNode; 
7.  } else { 
8.   Node tempNode = firstNode; 
9.   for (int i = 0; i <= index; i++) { 
10.    if (i == index - 1) { 
11.     tempNode = tempNode.getNext(); 
12.     return tempNode; 
13.    } 
14.   } 
15.   System.out.println("objectLinkedList get method nothing found"); 
16.   return null; 
17.  } 
18. } 

А на линии 6 и 12 вы можете увидеть проблему: функция возвращающую Node, когда мы на самом деле хотим Money; или, более конкретно, значение Node в качестве объекта.Таким образом, следующие изменения могут быть сделаны эти строки

6.  return firstNode.getValue(); 

и

12. return tempNode.getValue(); 

и последующего запуска testAdd снова он должен пройти.

Возможно, это будет не исправить все ошибки, которые содержатся в коде, но дает вам представление о шагах, которые необходимо предпринять, чтобы найти проблему.

Ваш код хорошо отформатирован, вы приложили усилия, чтобы поместить javadoc в свои функции, и вы настойчивы. Хорошая работа, держись за нее.

+0

Привет, я принял ваш совет, но теперь у меня ошибка тезисов. Я обновил свой вопрос, не могли бы вы взять его снова? Спасибо –

+0

@JINYUWU Конечно, какая IDE вы используете? – Nic

+0

Я использую NetBean –

0

Проблема заключается в методе size(), вы не принимать во внимание два крайних случаях:

  1. Когда список пуст (вы получите NPE для пытается выполнить n.getNext()

  2. Когда есть только один узел в списке (он не имеет «следующий», поэтому он будет возвращать ноль вместо 1)

Вы можете легко исправить, добавив следующую строку в начале метода:

public int size() { 
     int size = 1; 
     if (firstNode == null) { 
      return 0; 
     } 
     try {... 

Существует еще одна ошибка в методе add. Для цикла излишне сложный и не обрабатывает некоторые случаи ребер. Измените его так:

public void add(int index, Object obj) { 
    Node tempNode = firstNode; 
    Node currentNode = new Node(obj); 
    if (index < 0 || index > size()) { 
     System.out.println("add(ObjectLinkedList) index out of bound exception: " + index + "; size: " + size()); 
    } else if (index == 0) { 
     firstNode = currentNode; 
    } else { 
     for (int i = 0; i < index-1; i++) { 
      tempNode = tempNode.getNext(); 
     } 
     tempNode.setNext(currentNode); 
    } 
} 

И код будет работать.

Кроме того, я бы также «обновить» toString метод что-то вроде:

@Override 
public String toString() { 
    Node tmp = firstNode; 
    String res = "" + firstNode; 
    while (tmp.getNext() != null) { 
     tmp = tmp.getNext(); 
     res += "," + tmp; 
    } 
    return "ObjectLinkedList{" + res + "}"; 
} 

Таким образом, при печати списка вы сможете увидеть все элементы, а не только первый.

+0

после добавления кода я получил 1, хотя. Это должно быть 2 –

+0

Это потому, что у вас есть еще одна ошибка в 'add'. См. Обновленный ответ. – alfasin

+0

Я изменил свой код, как вы, но у меня все еще есть ошибка. и теперь возникает проблема с методами add, find, removeAt и remove. Я думаю, что проблема заключается в моем методе size(). но я не смог найти ошибку –

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

  • Нет связанных вопросов^_^