标题令人困惑,但我不知道如何用其他方式描述它。我正在构建一个汽车对象的链表,一切都很好,我正在通过调用getElement方法打印列表。如果它在克尔维特上这样做,那么System.out.print(corvette.getElement);
,它只会像我希望的那样显示corvette
。但如果我在corvette
在列表中时对我的traverse
方法也这样做,它会吐出linklist.Cars@5f531aca
。下面的代码。
public class LinkList <E>
{
private Cars<E> head;
private Cars<E> tail;
private static int length;
public int getLength()
{
return length;
}
public LinkList()
{
tail = new Cars();
head = new Cars(null, tail);
length = 0;
}
public void traverse()
{
Cars<E> cursor = head.getSuccessor();
while(cursor != tail)
{
System.out.println(cursor.getElement());
cursor = cursor.getSuccessor();
}
}
public Cars<E> find(int pos)
{
if(pos < 0 || pos >= this.length)
{
throw new IndexOutOfBoundsException();
}
Cars<E> cursor = head.getSuccessor();
for(int index = 0; index < pos; ++index)
{
cursor = cursor.getSuccessor();
}
return cursor;
}
public Cars<E> find(E element)
{
Cars<E> cursor = head.getSuccessor();
while(cursor != tail)
{
if(!cursor.getElement().equals(element))
cursor = cursor.getSuccessor();
else return cursor;
}
return null;
}
public void addAtHead(E element)
{
Cars<E> newNode = new Cars<>(element, null);
newNode.setSuccessor(head.getSuccessor());
head.setSuccessor(newNode);
++length;
}
public void insert(E element, int pos)
{
if(pos < 0 || pos > this.length)
{
throw new IndexOutOfBoundsException();
}
if(pos == 0)
{
addAtHead(element);
}
else if(pos == length)
{
addAtTail(element);
}
else
{
Cars<E> newNode = new Cars<>(element, null);
Cars<E> prevNode = find(pos - 1);
newNode.setSuccessor(prevNode.getSuccessor());
prevNode.setSuccessor(newNode);
++length;
}
}
public void addAtTail(E element)
{
Cars<E> newNode = new Cars<>(element, null);
if(length > 0)
{
Cars<E> lastNode = find(this.length - 1);
newNode.setSuccessor(lastNode.getSuccessor());
lastNode.setSuccessor(newNode);
}
else
{
newNode.setSuccessor(head.getSuccessor());
head.setSuccessor(newNode);
}
++length;
}
public E delete(int pos)
{
if(pos < 0 || pos >= this.length)
{
throw new IndexOutOfBoundsException();
}
Cars<E> prevNode;
if(pos == 0)
{
prevNode = head;
}
else
{
prevNode = find(pos - 1);
}
Cars<E> poorUnfortunateSoul = prevNode.getSuccessor();
prevNode.setSuccessor(poorUnfortunateSoul.getSuccessor());
poorUnfortunateSoul.setSuccessor(null);
--length;
return poorUnfortunateSoul.getElement();
}
public static void main(String[] args)
{
Cars corvette = new Cars("corvette", null);
Cars pinto = new Cars("pinto", null);
Cars mustang = new Cars("mustang", null);
Cars bmw = new Cars("bmw", null);
Cars elio = new Cars("elio", null);
LinkList list = new LinkList();
list.addAtTail(corvette);
list.addAtTail(pinto);
list.addAtTail(mustang);
list.addAtTail(bmw);
list.addAtTail(elio);
System.out.println(corvette.getElement());
list.traverse();
接下来是我的汽车课。
public class Cars <E>
{
private E element;
private Cars successor;
public Cars()
{
this.element = null;
this.successor = null;
}
public Cars(E element, Cars<E> node)
{
this.element = element;
this.successor = node;
}
public E getElement()
{
return this.element;
}
public void setElement(E element)
{
this.element = element;
}
public Cars<E> getSuccessor()
{
return this.successor;
}
public void setSuccessor(Cars successor)
{
this.successor = successor;
}
}
本质上,测试方法输出:
corvette
linklist.Cars@5f531aca
linklist.Cars@4903f4aa
linklist.Cars@22b3ea59
linklist.Cars@51de8adb
linklist.Cars@696e59da
我不知道为什么,当他们都只是打印getElement
方法时。有什么想法吗?
编辑:我知道这是一种愚蠢的做事方式,但它就是这样(任务(。我真正想知道的是,为什么traverse
方法中的corvette.getElement()
和cursor.getElement
提供了不同的东西,而它们(据我所知(应该执行完全相同的操作。
public void addAtTail(E element)
这应该需要E
。在您的情况下,是类似于"corvette"
的字符串。
但是您使用Cars<E>
调用该方法。
Cars corvette = new Cars("corvette", null);
list.addAtTail(corvette);
结果,您的列表元素被包装了两次。
Cars<E> newNode = new Cars<>(element, null);
你没有收到一些类型的警告吗?
你应该利用你的通用类型:
Cars<String> corvette = new Cars("corvette", null);
然后编译器将检测到类型不匹配并拒绝编译此代码。
您的错误在于addAtTail
方法接受E
作为参数,而不是像您提供的那样接受Car
。你应该打电话给addAtTail("corvette")
。如果你真的使用了泛型类,这个问题就会避免——这就是它的作用。使用LinkList<String> list = new LinkList<String>();
而不是LinkList list = new LinkList();
(因为在本例中您将字符串放在列表中(,类似地,您的Cars
应该是Cars<String>
。这将防止您意外地将错误的类型添加到列表中,就像本例中发生的那样。
编辑:此外,您的代码似乎混淆了什么是汽车,什么是列表中的元素。您的Cars
类实际上似乎并不代表一辆汽车。汽车对象不需要知道列表中哪辆车在它后面。您可能应该将Cars
类重命名为类似于ListNode
的类,因为它的每个实例代表列表的一个节点。这个节点本身不是一辆车,但它应该包含一辆车——这就是元素字段的用途。Cars
类将仅具有关于汽车的信息。然后你会有这样的东西:
LinkList<Car> list = new LinkList<Car>;
list.addAtTail(new Car("corvette"));
然后,addAtTail
方法将创建一个包含您刚刚创建的汽车的ListNode<Car>
对象,并将其添加到列表中。