在同一对象上调用时不返回相同的方法

时间:2014-07-10 03:02:58

标签: java methods printing linked-list traversal

标题令人困惑,但我不知道如何描述它。我正在构建一个Cars对象的链接列表,一切都很好,我通过调用我的getElement方法打印列表。如果它是在让我们说corvette,System.out.print(corvette.getElement);,它就像我想要的那样显示corvette。但是,如果我在列表中traverse时使用corvette方法执行相同操作,则会吐出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方法时,我不知道为什么。有什么想法吗?

编辑:我知道这是一种愚蠢的做事方式,但事实就是如此(任务)。我真正想知道的是,corvette.getElement()方法中cursor.getElementtraverse为什么提供不同的东西,当它们(据我所知)应该执行完全相同的操作时。< / p>

2 个答案:

答案 0 :(得分:0)

  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);  

然后编译器会检测到类型不匹配并拒绝编译此代码。

答案 1 :(得分:0)

您的错误在于,addAtTail方法接受E作为参数,而不是您提供的Car。你应该致电addAtTail("corvette")。如果你真的使用了泛型类,就可以避免这个问题 - 这就是它的用途。而不是LinkList list = new LinkList();,请使用LinkList<String> list = new LinkList<String>();(因为在这种情况下您将字符串放入列表中),同样地,Cars应该是Cars<String>。这将使您不会意外地将错误的类型添加到列表中,就像在这种情况下发生的那样。

编辑:此外,您的代码似乎混淆了什么是汽车以及列表的元素。您的Cars课程实际上并不代表汽车。没有必要让汽车对象知道列表中的汽车是哪辆汽车。您可能应该将Cars类重命名为ListNode,因为它的每个实例代表列表的一个节点。这个节点本身不是汽车,但它应该包含汽车 - 这就是元素字段的用途。然后Cars班级将获得有关汽车的信息。然后你会有这样的东西:

LinkList<Car> list = new LinkList<Car>;
list.addAtTail(new Car("corvette"));

addAtTail方法会创建一个包含您刚创建的汽车的ListNode<Car>对象,并将其添加到列表中。