方法在对同一对象调用时未返回相同的值



标题令人困惑,但我不知道如何用其他方式描述它。我正在构建一个汽车对象的链表,一切都很好,我正在通过调用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>对象,并将其添加到列表中。

相关内容

  • 没有找到相关文章

最新更新