简体   繁体   English

ArrayList的add()方法很奇怪吗?

[英]ArrayList add() method acting weird?

I'm working on a (double) linked list implementation using "buckets". 我正在研究使用“存储桶”的(双)链表实现。 In short, A doubly linked list of nodes, each node holding an ArrayList of a set size specified by arguments. 简而言之,是一个双向链接的节点列表,每个节点都包含一个由参数指定大小的ArrayList。

I've Initialized my Nodes and list like this: 我已经初始化了我的节点并列出如下:

public class MyLinkedList<T> implements ADTListInterface<T> {

ArrayList<T> list;

private class Node {

    T value;
    Node next;
    Node previous;
    ArrayList<T> list;

    public Node(Node n, Node p) {

        list = new ArrayList<T>(bucketSize);
        next = n;
        previous = p;
    }
}

private Node head;
private Node tail;
private int bucketSize;

public MyLinkedList(int bucketSize) {

    this.bucketSize = bucketSize;
    head = tail = new Node(null, null);

}

and I have set up my add method like this: 并且我已经设置了我的add方法,如下所示:

    public void add(T o) {

    Node current = head;

    while (current.list.add(o) != true) {

        if (current.next != null) {

            current = current.next;
        }

        if (current.next == null) {

            current.next = new Node(null,current);
        }
    }
}

When testing the add method with bucketSize = 3 and the following commands: 当使用bucketSize = 3和以下命令测试add方法时:

list.add("a");
list.add("b");
list.add("c");

I expect the head node to contain a list with elements and order as follows: 我希望头节点包含一个包含元素和顺序的列表,如下所示:

c,b,a C,B,一个

However, the line: current.list.add(o) appears to add the specified object multiple times until it fills the list. 但是,以下行:current.list.add(o)似乎多次添加指定的对象,直到它填满列表。 so my node turns out to contain the elements: 所以我的节点原来包含以下元素:

a,a,a A,A,A

Thank you in advance for looking at my code. 预先感谢您查看我的代码。

Part of your problem lies in your logic that prints the content of the list and part of it is in your add method. 问题的一部分在于打印列表内容的逻辑,而一部分则在add方法中。 First of all your current node is a local variable of add method. 首先,当前节点是add方法的局部变量。 That means second 'if' statement: 这意味着第二个“如果”陈述:

if (current.next != null) {

            current = current.next;
}

is not doing anything useful. 没有做任何有用的事情。 You set current to point at the same object as current.next does but then you leave the method and your reference is destroyed. 您将current设置为指向与current.next相同的对象,但是随后离开该方法,并且引用被破坏。 It does not make sense. 它没有任何意义。

Assuming you invoked constructor of your list and then added three elements: "a", "b", "c" here is how your Node objects will behave on heap. 假设您调用了列表的构造函数,然后添加了三个元素:“ a”,“ b”,“ c”,这是Node对象在堆上的行为。

After constructor finished there is one Node object on the heap which looks like: { list -> {empty}, prev -> null, next -> null } this object is referenced by the head and tail reference variables. 构造函数完成后,堆上将出现一个Node对象,如下所示:{list-> {empty},prev-> null,next-> null}此对象由头和尾引用变量引用。 Note that if you invoke new ArrayList(bucketSize) it will create empty list with 'bucketSize' initial capacity. 请注意,如果您调用新的ArrayList(bucketSize),它将创建初始容量为'bucketSize'的空列表。

After 1st call to add("a"): 在第一次调用add(“ a”)之后:

nodeObject#1 : { list -> {"a"}, prev -> null, next -> nodeObject#2 } nodeObject#1:{列表-> {“ a”},上一个-> null,下一个-> nodeObject#2}

nodeObject#2 : { list -> {empty}, prev -> nodeObject#1, next -> null} nodeObject#2:{列表-> {空},上一个-> nodeObject#1,下一个->空}

nodeObject#1 is accesible via head or tail. nodeObject#1可通过头部或尾部访问。 nodeObject#2 is accesible via head.next or tail.next. 通过head.next或tail.next可访问nodeObject#2。

After 2nd call to add("b"): 第二次调用add(“ b”)之后:

nodeObject#1 : { list -> {"a","b"}, prev -> null, next -> nodeObject#2 } nodeObject#1:{列表-> {“ a”,“ b”},上一个-> null,下一个-> nodeObject#2}

nodeObject#2 : { list -> {empty}, prev -> nodeObject#1, next -> null} nodeObject#2:{列表-> {空},上一个-> nodeObject#1,下一个->空}

After 3rd call to add("c"): 第三次调用add(“ c”)之后:

nodeObject#1 : { list -> {"a","b","c"}, prev -> null, next -> nodeObject#2 } nodeObject#1:{列表-> {“ a”,“ b”,“ c”},上一个-> null,下一个-> nodeObject#2}

nodeObject#2 : { list -> {empty}, prev -> nodeObject#1, next -> null} nodeObject#2:{列表-> {空},上一个-> nodeObject#1,下一个->空}

Also having prev and next in your Node suggest that your list should be bi directional that means you need to implement methods like add_at_the_end and add_at_the_beginning but that's a different story ( I can show some examples too if needed ). 在Node中也有prev和next建议您的列表应该是双向的,这意味着您需要实现add_at_the_end和add_at_the_beginning之类的方法,但这是一个不同的故事(如果需要,我也可以显示一些示例)。 The next question is why you use ArrayList as a Node class field. 下一个问题是为什么将ArrayList用作Node类字段。 T value should be enough. T值应该足够。

Here is my example of simple list implementation without ArrayList. 这是我没有ArrayList的简单列表实现的示例。 There is iterator method that returns instance of Iterator which can be used to display list's elements. 有迭代器方法返回迭代器的实例,该实例可用于显示列表的元素。

package com.playground;

import java.util.ArrayList;
import java.util.Iterator;

class CustomList<T>{
    private class Node{
        Node prev;
        Node next;

        T value;
        Node(T rVal, Node p, Node n){
            this.value = rVal;
            this.prev = p;
            this.next = n;
        }
        void setNext(Node n){ this.next = n; }
        void setPrev(Node p){ this.prev = p; }
    }

    private Node head;
    private Node tail;



    public void add(T element) {
        if(tail == null && head == null){
            head = new Node(element, null,null);
            tail = head;
        }
        else{
            Node tmp = new Node(element, tail, null);
            tail.setNext( tmp );
            tail = tmp;
        }

    }

    public Iterator<T> iterator() {

        return new Iterator<T>(){
            Node current = head;
            @Override
            public boolean hasNext() {
                // TODO Auto-generated method stub
                return current != null;
            }

            @Override
            public T next() {
                Node tmp = current;
                current = tmp.next;
                return tmp.value;
            }

            @Override
            public void remove() {
                // TODO Auto-generated method stub

            } };
    }

}

public class CustomListTest {
    public static void main(String [] args){
        CustomList<String> list = new CustomList<String>();
        list.add("my");
        list.add("custom");
        list.add("list");       

        Iterator<String> forwardIterator = list.iterator();
        while( forwardIterator.hasNext()){
            System.out.println( forwardIterator.next());
        }

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM