我正在尝试创建自定义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() {
}
}
这是我得到的错误:
我的节点类:
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 :(得分:0)
问题在于size()
方法,你没有考虑两个边缘情况:
当列表为空时(您将获得NPE以尝试执行n.getNext()
当列表中只有一个节点时(它没有“下一个”,所以它将返回零而不是1)
您可以通过在方法开头添加以下内容轻松修复它:
public int size() {
int size = 1;
if (firstNode == null) {
return 0;
}
try {...
方法add
中还有另一个错误。 for循环不必要地复杂并且不处理某些边缘情况。将其修改为:
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 + "}";
}
这样,当您打印列表时,您将能够看到所有元素,而不仅仅是第一个元素。
答案 1 :(得分:0)
我认为这是为了练习或分配,java已经LinkedList
的通用实现see the api docs。
您可以在java helpul中找到许多texts数据结构中的一个,但通常它们的实现使用泛型而不是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
修改强>
当get方法尝试调用testRemoveAt()
时,NullPointerException
将抛出tempNode.getNext().getValue()
,但在测试删除第二个对象之后,列表中只有一个Money对象getNext()
java.lang.AssertionError:
Expected :Node@4f2410ac
Actual :Money@722c41f4
assertEquals(list.get(0), m1);
1}}返回null。
修改2
您可能最熟悉调试器。也许试试netbeans的视频教程。然后,您调查您的例外情况。例如,运行第一个测试会给出:
assertEquals
这意味着testAdd()测试在调用assertEquals(m1, list.get(0));
此处需要注意的是java.lang.AssertionError:
Expected :Money@722c41f4
Actual :Node@4f2410ac
的签名首先取其预期值,然后取实际值。因此,将该行更改为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. }
对象,这意味着测试正确,我们需要看一下执行Node
。
你有:
Money
在第6和第12行,你可以看到问题:当我们真正想要Node
时,函数返回6. return firstNode.getValue();
;或者更具体地说,12. return tempNode.getValue();
作为对象的值。因此,可以对这些行进行以下更改
testAdd
和
jsonp
然后再次运行beforeSend
它应该通过。
这可能不修复代码中的所有错误,但它会让您了解要找到问题的步骤。
您的代码格式正确,您已经努力将javadoc放在您的函数上,并且您将继续执行。干得好,坚持下去。