【问题标题】:How do I add objects into a linked list?如何将对象添加到链表中?
【发布时间】:2013-02-23 08:22:34
【问题描述】:

我一直在做一个项目,我必须实现一个 java 类来实现双向链表的使用。我用我的所有方法完成了 LinkedList 类。我只是不确定如何将节点对象实际添加到列表中。到目前为止,这是我的代码,底部有测试。任何帮助,将不胜感激。谢谢

public class LinkedList {

    private Node first;
    private Node current;
    private Node last;
    private int currentIndex;
    private int numElements;

    public LinkedList() {
        this.first = null;
        this.last = null;
        this.numElements = 0;
        this.current = null;
        this.currentIndex = -1;
    }

    private class Node {

        Node next;
        Node previous;
        Object data;
    }

    public boolean hasNext() {
        return (current != null && current.next != null);
    }

    public Object next() {
        if (!this.hasNext()) {
            throw new IllegalStateException("No next");
        }

        current = current.next;
        return current.data;

    }

    public boolean hasPrevious() {
        return (current != null && current.previous != null);

    }

    public Object previous() {
        if (!this.hasPrevious()) {
            throw new IllegalStateException("No previous");
        }
        current = current.previous;
        return current.data;

    }

   int nextIndex() {
        int index = numElements;
        if (hasNext()) {
            index = this.currentIndex + 1;
        }
        System.out.println(index + "The current index is " + current);
        return index;
    }

    int previousIndex() {
        int index = -1;
        if (hasPrevious()) {
            index = this.currentIndex - 1;
        }
        System.out.println(index + "The current index is " + current);
        return index;
    }

    public void set(Object o) {
        if (this.current == null) {
            throw new IllegalStateException("No node found, cannot set.");
        }
        current.data = o;
    }

    public int size() {
        return numElements;
    }

    public void add(Object o) {       
        Node newNode = new Node();
        newNode.data = o;
        if (first == null) {
            first = newNode;
            last = newNode;
            newNode.next = null;

        } else if (first != null) {
            if (current == null) {
                newNode.previous = null;
                newNode.next = first;
                first.previous = newNode;
                first = newNode;
            } else if (current == last) {
                newNode.previous = current;
                newNode.next = null;
                current.next = newNode;
                last = newNode;
            } else {
                newNode.previous = current;
                newNode.next = current.next;
                current.next.previous = newNode;
                current.next = newNode;
            }
        }
        current = newNode;
        numElements++;
        currentIndex++;

    }

    public void remove() {
        if (current != null) {
            if (current == first && current == last) {
                first = null;
                last = null;
            } else if (current == last) {
                current.previous = null;
                last = current.previous;
            } else if (current == last) {
                current.previous.next = null;
                last = current.previous;
            } else {
                current.previous.next = current.next;
                current.next.previous = current.previous;
            }
            current = current.next;
            numElements--;
        }
    }
}



import java.util.Scanner;


public class LinkedListTest {
    public static void main(String[] args) {
        Scanner keyboard = new Scanner(System.in);
        String name;
        int index;

        LinkedList<Object> listOne = new LinkedList<Object>();

        listOne.add(object o);

    }
}

【问题讨论】:

  • 对测试课感到抱歉,我知道这是可耻的
  • 到目前为止,您似乎走在了正确的轨道上。你的输出给了你什么,你期望得到什么?
  • listOne.add(newNode) 中的对象 newNode 来自哪里?此外,您真的应该考虑使用泛型。
  • 我不出来把错误写成“类型 LinkedList 不接受参数”
  • 对不起,应该不是newNode,应该是Object o

标签: java linked-list doubly-linked-list


【解决方案1】:

发布的类 LinkedList 对我来说看起来很实用。

确保您的测试代码不会混淆此类和 Java 为您提供的 java.util.LinkedList(它是现有 Collections 框架的一部分)。

为清楚起见,我建议将您的课程重命名为 MyLinkedList

以下代码有效,输出为“0”,“2”:

public class MyLinkedListTest {

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

        MyLinkedList list = new MyLinkedList();
        System.out.println("Number of items in the list: " + list.size());

        String item1 = "foo";
        String item2 = "bar";

        list.add(item1);
        list.add(item2);

        System.out.println("Number of items in the list: " + list.size());      

        // and so on...
    }

}

【讨论】:

  • 这似乎是最好的方法。谢谢
【解决方案2】:

如果您的代码已编译,我会感到惊讶,因为您的类实际上并不是通用的。只需将其初始化为LinkedList listOne = new LinkedList();(无尖括号)。

至于实际添加元素,您只需要添加一些Objectinstance;任何事情都会做(假设您的内部代码正常工作)。在最后尝试一下:

Object objectToAdd = "Strings are Objects";
listOne.add(objectToAdd);
objectToAdd = new File("C:\\foo.bar"); // Or use any other Objects!
listOne.add(objectToAdd);

【讨论】:

  • 我也发现了这个。他可能需要小心,因为某些 IDE 会自动导入 Java LinkedList,这会导致混淆。
  • @Cliff 我假设他没有使用 IDE,否则它会警告他 listOne.add(object o); 不会编译,但这肯定是一个有效的问题。
  • 没错,但如果他是编码新手,他很可能在没有注意到的情况下输入了警告。
【解决方案3】:

想想编号列表,看看元素之间的关系

假设我有清单:

  1. 一个
  2. B
  3. C

我要对关系做些什么得到列表:

  1. 一个
  2. B
  3. 新节点
  4. C

B的新下一个节点是NewNode C 的新的前一个节点是 NewNode。因此,插入函数会想知道紧邻的前一个节点或紧邻的下一个节点,然后调整关系。

【讨论】:

  • 这与他的问题有何关系?
  • @HenryKeiter "如何将对象添加到链接列表中?"这显然是作业,因此我用英语而不是代码解释了如何。
  • 他已经有密码了。他实际上是在询问如何实例化列表并向其中添加对象。这是一个语法问题,而不是实现。
【解决方案4】:

您的 LinkedList 没有泛型类型,因此您不能将其声明为

LinkedList<Object> listOne = new LinkedList<Object>();

而是作为

LinkedList listOne = new LinkedList();

现在添加元素只需使用您的 add 方法

listOne.add("something");
listOne.add(1);//int will be autoboxed to Integer objects

另外,如果你想从键盘添加数据,你可以使用类似

String line="";
do{
    System.out.println("type what you want to add to list:");
    line = keyboard.nextLine();
    listOne.add(line);
}while(!line.equals("exit"));

【讨论】:

  • 这行得通,我之前也有类似的代码,但如果我使用字符串“Something”或 int 1,它们是否被视为对象?
  • @joe String 是一个类,并且所有类在某些时候都扩展了Object 类,因此它们的实例可以作为对象受到威胁。对于1,它是原始类型int,但在这种情况下,当您使用原始类型作为期望Object 的参数时,它将是autoboxedInteger,它也会在某个点扩展Object,因此它会起作用.
【解决方案5】:

线

LinkedList&lt;Object&gt; listOne = new LinkedList&lt;Object&gt;();

除非您将类声明更改为

,否则不会编译

class LinkedList&lt;T&gt;

或者你也可以写

LinkedList listOne = new LinkedLis();

之后,您应该能够将对象添加到您的列表中。但是,您需要创建一个对象来添加它,listOne.add(object o); 不会这样做——至少您必须编写listOne.add(new Object())。 (您的代码没有实例化一个 Object,没有您已经调用过 o 的 Object,此外,object o 在 Java 中没有任何意义,也不会编译。

【讨论】:

  • 我明白了。因此,如果我创建一个类,例如 Car。我是否必须每次都创建一辆新车,或者我可以使用我的默认构造函数将多个相同的默认汽车添加到列表中?
  • 您当然可以将多个相同的默认汽车添加到列表中,但是您到底想实现什么?为什么你想要一个完全相同的汽车对象的列表?
  • 更重要的是,如果您将一个对象的同一个实例多次添加到您的列表中,您将如何验证,例如,是否以正确的顺序正确添加了对象?您列表中的所有对象看起来都相同,您将无法从中获取任何信息。
【解决方案6】:

正如人们所提到的,您的列表并不通用。但是,由于他们建议您删除该参数,您也可以将 &lt;Object&gt;&lt;E&gt; 添加到您的链表实现中,并保持您对列表的初始化不变。

因此,在您的链表类中,您应该执行以下操作:

public class LinkedList<E>

这将确保当您使用 LinkedList&lt;Object&gt; listOne = new LinkedList&lt;Object&gt;(); 时,E 将被转换为 Object

【讨论】:

    【解决方案7】:

    让我们稍微改进一下您的测试,以便您的问题出在哪里(如果有的话)我注释掉了对 current() 方法的调用,因为您没有包含一个。 (我会不理会它,因为它可能会让您感到困惑。)一般的想法是将项目添加到链接列表中,并在它中前后移动检查每个步骤的项目。

    public class LinkedListTest {
        public static void main(String[] args) {
            Scanner keyboard = new Scanner(System.in);
            String name;
            int index;
    
            LinkedList listOne = new LinkedList();
            //Initially we should be empty so we are positioned
            // at both the beginning and end of the list
            assert listOne.size() == 0 :"List should be empty";
            assert listOne.hasPrevious()==false: "Should be at the beginning of the list";
            assert listOne.hasNext()==false : "Should be at the end of the list";
    
            Object firstNode = "I am the first node";
            listOne.add(firstNode); //we've added something
    //I left this commented out since you don't have a current() method.
    //        assert firstNode == listOne.current() : "Our current item should be what we just added";
            assert listOne.hasPrevious()==false : "Should not have moved forward in our list yet";
            assert listOne.hasNext()==true : "should have an item after our current";
            assert listOne.size() == 1 : "Should only have one item in the list";
            Object secondNode = "I am the second node";
            listOne.add(secondNode);
            assert listOne.size() == 2 : "Should only have two items in the list";
    
            assert firstNode == listOne.next() : "1st call to next should return the 1st node";
            assert listOne.hasPrevious()==true : "We should be positioned after the 1st node";
            assert listOne.hasNext()==true : "We should be positioned before the 2nd node";
        }
    }
    

    【讨论】:

    • 在Java中使用off Assert是常见的做法吗?#
    • 这取决于你在哪里工作! :D 我在这里使用断言来说明代码是如何工作的。许多人会使用完整的 JUnit 框架来做同样的事情。无论哪种方式,您都可以在不使用调试器的情况下调试您的代码、发现解决方案的增量方法以及永不过时的内置文档。
    猜你喜欢
    • 2013-09-30
    • 2019-05-05
    • 1970-01-01
    • 2023-03-31
    • 2017-05-26
    • 2015-12-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多