Java 为什么我的定制LinkedList不起作用?
我正在尝试创建定制的LinkedList,以便更好地理解数据结构。我不知道我的LinkedList类有什么问题Java 为什么我的定制LinkedList不起作用?,java,data-structures,collections,linked-list,nodes,Java,Data Structures,Collections,Linked List,Nodes,我正在尝试创建定制的LinkedList,以便更好地理解数据结构。我不知道我的LinkedList类有什么问题 package numberlist.primitivelist.objectlist; public class ObjectLinkedList extends ObjectList implements Copiable { Node firstNode; /** * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * *
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;
}
}
以下是我得到的错误:
我的节点类:
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;
}
}
问题在于
size()
方法中,您没有考虑两种边缘情况:
n.getNext()
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);
}
}
这样,当您打印列表时,您将能够看到所有元素,而不仅仅是第一个元素。我假设这是为了练习或分配,java已经有了
LinkedList的通用实现
您可能会发现java中许多关于数据结构的方法中的一种很有帮助,尽管它们的实现通常使用泛型而不是对象
对于您的特定问题,您注意到在testAdd方法中您调用了
assertEquals(list.get(0), m1);
这是将节点
与总是失败的货币
对象进行比较
您可以assertEquals(list.get(0).getValue(),m1);
除非更改get()
方法以返回节点,而不是当前执行的对象,否则此操作将不起作用
其他测试也存在类似问题,其中list.get()
返回一个节点,而不是该节点中的数据
或者,编辑get()
方法以返回节点中的数据:
...
} else if (index == 0) {
return firstNode.getValue();
} else {
// etc, you have multiple returns in this method
编辑
当get方法试图调用tempNode.getNext().getValue()
时,您的testRemoveAt()
将抛出一个NullPointerException
,但在测试删除第二个对象后,列表中只有一个Money对象,因此getNext()
返回null
编辑2
对您来说,更熟悉调试器可能是最有用的。您可以尝试一个视频教程。然后您可以调查您的异常。例如,运行第一个测试可以提供:
java.lang.AssertionError:
Expected :Node@4f2410ac
Actual :Money@722c41f4
这意味着testAdd()测试在调用assertEquals(list.get(0),m1);
这里需要注意的是,assertEquals
的签名首先取预期值,然后取实际值。因此,将该行更改为assertEquals(m1,list.get(0));
并重新运行测试
现在输出为:
java.lang.AssertionError:
Expected :Money@722c41f4
Actual :Node@4f2410ac
因此,测试需要一个Money
对象(这是m1
参数),但是list.get(0)
返回了一个节点
对象
要么测试预期的是错误的东西,要么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. }
及
然后再次运行testAdd
,它应该会通过
这可能不会修复代码中的所有bug,但它为您提供了查找问题所需的步骤
你的代码格式很好,你努力将javadoc放在你的函数上,而且你是持久的。做得好,坚持下去。类节点是如何定义的?还有,你是如何调试代码的?你的发现是什么,你能提供一个行为仍然奇怪的较小的代码段吗?添加代码后,我得到了1个答案呃。应该是2,这是因为您在add
中有另一个错误。请参阅更新的答案。我像您一样修改了我的代码l,但仍然存在错误。现在,我的add、find、removeAt和remove方法有问题。我想问题在于我的大小()方法,但我找不到error@JINYUWU问题是什么?尽量提供更多细节,否则很难帮助你。你好,我接受了你的建议,但现在我发现这些错误。我更新了我的问题。你能再接受一次吗?Thanks@JINYUWU确定你用的是什么IDE吗?我用的是NetBean谢谢,我遵循你的做法,它是p但是我的removeAt和remove方法有错误吗?因为我一直在获取NPEHi@JINYUWU。我在前面的第一次编辑中提到了这一点。这是因为代码试图调用getValue()
在null
节点上进行调试。调试是一项非常有价值的技能,最好通过实践来学习,我建议您解决其他bug。
java.lang.AssertionError:
Expected :Money@722c41f4
Actual :Node@4f2410ac
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. return firstNode.getValue();
12. return tempNode.getValue();