使用toString打印链表

8
好的,朋友们。我正在尝试学习如何打印链表。我具备使用此列表所需的所有方法,但是我无法找出如何显示节点的值。现在我的主方法中没有任何内容,因为我一直在尝试在主方法中调用非静态方法而出现错误。我有一个toString方法,可以显示列表的内容。我该如何调用此toString来显示每个节点的值?任何建议都将不胜感激。
以下是节点类:
public class LinkedListNode
{

    private int data;
    private LinkedListNode next;


    public LinkedListNode(int data)
    {
        this.data = data;
        this.next = null;
    }

    public int getData()
    {
        return data;
    }

    public void setData(int d)
    {
        data = d;
    }

    public LinkedListNode getNext()
    {
        return next;
    }

    public void setNext(LinkedListNode n)
    {
        next = n;
    }
}

这里是包含主要方法以操作链表的LinkedList类:

public class LinkedList {

    public LinkedListNode head;

    public static void main(String[] args) {

    LinkedList l = new LinkedList();
    l.insertFront(0);
    System.out.println(l.toString());

    }

    public LinkedList() {
        this.head = null;
    }

    public int removeFront(){
        if(head == null){
            System.out.println("Error - Attempting to call removeFront() on empty list");
            return 0;
        }else{
            int temp = head.getData();
            head = head.getNext();  
            return temp;
        }

    }

    public void insertFront(int data){
        if(head == null){
            head = new LinkedListNode(data);
        }else{
            LinkedListNode newNode = new LinkedListNode(data);
            newNode.setNext(head);
            head = newNode;
        }       
    }

    public void insertBack(int data){
        if(head == null){
            head = new LinkedListNode(data);
        }else{
            LinkedListNode newNode = new LinkedListNode(data);
            LinkedListNode current = head;
            while(current.getNext() != null){
                current = current.getNext();
            }
            current.setNext(newNode);
        }       
    }

    public int removeBack(){
        if(head == null){
            System.out.println("Error - Attempting to call removeBack() on empty list");
            return 0;
        }else if (head.getNext() == null){
            int temp = head.getData();
            head = null;
            return temp;
        }else{

            LinkedListNode current = head;
            while(current.getNext().getNext() != null){
                current = current.getNext();
            }
            int temp = current.getNext().getData();
            current.setNext(null);
            return temp;
        }       
    }

    public String toString(){
        String retStr = "Contents:\n";

        LinkedListNode current = head;
        while(current != null){
            retStr += current.getData() + "\n";
            current = current.getNext();

        }

        return retStr;
    }

    public LinkedListNode getHead() {
        return head;
    }

    public void setHead(LinkedListNode head) {
        this.head = head;
    }
}

2
你创建一个类的实例并在其上调用 toString() - Sotirios Delimanolis
1
调用 toString() 方法。我认为这没有任何问题。 - Prateek
你是什么意思?如果我在主方法中调用“toString()”,我会收到一个错误,说“无法对非静态方法toString()进行静态引用”。 - Shawn
所以,我尝试了一下。我初始化了新实例。之后,我使用l.insertFront(0)添加了第一个节点的值。然后,在此之后,我调用了toString方法,但是当我运行程序时它没有显示任何内容? - Shawn
1
愚蠢的问题:你刚才是调用了 toString,还是对结果进行了某些操作(例如 System.out.println(I.toString());)?(或者使用 System.out.print,因为结果已经以换行符结尾。) - ajb
显示剩余2条评论
6个回答

7
public static void main(String[] args) {

    LinkedList list = new LinkedList();
    list.insertFront(1);
    list.insertFront(2);
    list.insertFront(3);
    System.out.println(list.toString());
}

String toString() {
            String result = "";
            LinkedListNode current = head;
            while(current.getNext() != null){
                result += current.getData();
                if(current.getNext() != null){
                     result += ", ";
                }
                current = current.getNext();
            }
            return "List: " + result;
}

5
正如其他答案和评论中指出的那样,你在这里漏掉了调用JVM系统类来打印由你的toString()方法生成的字符串。
LinkedList myLinkedList = new LinkedList();
System.out.println(myLinkedList.toString());

这样做可以完成工作,但我不建议这样做。如果我们查看Object类的javadocs,我们会发现toString()的描述如下:
返回对象的字符串表示形式。通常,toString方法返回一个“文本表示”该对象的字符串。强调添加在此处是我的。您正在创建一个包含整个链表状态的字符串,这可能超出了使用您的类的人的预期。我建议进行以下更改:
1. 在LinkedListNode类中添加一个toString()方法。
2. 更新LinkedList类中的toString()方法,使其更加简洁。
3. 在LinkedList类中添加一个名为printList()的新方法,该方法执行您当前希望toString()执行的操作。
在LinkedListNode中:
public String toString(){
   return "LinkedListNode with data: " + getData();
}

在链表中:
public int size(){
    int currentSize = 0;
    LinkedListNode current = head;
    while(current != null){
        currentSize = currentSize + 1;
        current = current.getNext();
    }

    return currentSize;
}

public String toString(){
    return "LinkedList with " + size() + "elements.";
}

public void printList(){
    System.out.println("Contents of " + toString());

    LinkedListNode current = head;
    while(current != null){
        System.out.println(current.toString());
        current = current.getNext();
    }

}

1
当JVM尝试运行您的应用程序时,它静态调用您的主方法;类似以下内容:
LinkedList.main();

这意味着你的 LinkedList 类没有实例。为了调用你的 toString() 方法,你需要创建一个新的 LinkedList 类实例。
因此,你的 main 方法应该像这样:
public static void main(String[] args){
    // creating an instance of LinkedList class
    LinkedList ll = new LinkedList();

    // adding some data to the list
    ll.insertFront(1);
    ll.insertFront(2);
    ll.insertFront(3);
    ll.insertBack(4);

    System.out.println(ll.toString());
}

1
我是这样做的:

public static void main(String[] args) {

    LinkedList list = new LinkedList();
    list.insertFront(1);
    list.insertFront(2);
    list.insertFront(3);
    System.out.println(list.toString());
}

String toString() {
    StringBuilder result = new StringBuilder();
    for(Object item:this) {
        result.append(item.toString());
        result.append("\n"); //optional
    }
    return result.toString();
}

0
一个非常简单的解决方案是在Node中覆盖toString()方法。然后,您可以通过传递LinkedList的head来调用print。您不需要实现任何类型的循环。
代码:
public class LinkedListNode {
    ...

    //New
    @Override
    public String toString() {
        return String.format("Node(%d, next = %s)", data, next);
    }
} 


public class LinkedList {

    public static void main(String[] args) {

        LinkedList l = new LinkedList();
        l.insertFront(0);
        l.insertFront(1);
        l.insertFront(2);
        l.insertFront(3);

        //New
        System.out.println(l.head);
    }
}

0

对于@Marin代码,它没有涵盖列表为空或列表仅包含1个节点的情况。所以这里是改进后的代码:

 @Override
public String toString() {
    String result = "";
    LinkedListNode dummy = head;
    if (dummy == null) { //if list is empty return result
        return result;
    }else if(dummy.getNext() == null){ //if the list contains only 1 node
        result += dummy.getData();
        return result;
    }else{
        while(dummy != null){
            result += dummy.getData();
            if(dummy.getNext()!= null){
                result += " ";
            }
            dummy = dummy.getNext();
        }
        return result;
    }
    
    
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接