简体   繁体   English

ArrayList 正在替换项目而不是将其添加到末尾

[英]ArrayList is replacing item instead of adding it to end

I have a method that finds a node in a linked list with a certain id and adds items to the arraylist of that node.我有一种方法可以在具有特定 id 的链表中找到一个节点,并将项目添加到该节点的 arraylist 中。

ArrayList <String> elems;

public Place addElemToLst(String id, String elem) {
        
            // if no nodes create new node
            if (head == null) { 
                Node node = new Node(id);
                node.elems.add(item);
                head = unit;
            } else if (head != null) {
                Node curr = head;
                while (curr.next != null && !curr.next.id.equals(id)) {
                    curr = curr.next;
                }
                // if there is a id match
                if (curr.id.equals(id)) {
                    curr.elems.add(item);
                }
                // add new Node
                else { // the error is in this section
                    Node node = new Node(id);
                    node.elems.add(elem); 
                    curr.next = node;
                    
                }
        
        }

        return this;
    }

The problem is when I call addElemToLst() on an id of lets say "item1" multiple times and keep adding elements to the arraylist, the arraylist will only keep the last item entered into the arraylist.问题是当我在一个 ID 上调用 addElemToLst() 让我们说“item1”多次并继续向 arraylist 添加元素时,arraylist 将只保留最后一个输入 ZEB3A8342546F50C9CD18Z 的项目。 Essential, the arraylist is always a size of 1 because previous entries keep getting replaced.重要的是,arraylist 的大小始终为 1,因为以前的条目不断被替换。 Why is this and what is the error?为什么会这样,错误是什么? I have isolated the error to the comment in the code.我已将错误与代码中的注释隔离开来。 Thanks谢谢

You are not checking the first element/head for the correct ID您没有检查第一个元素/头部是否有正确的 ID

 while (curr.next != null && !curr.next.id.equals(id))

You can try something like this for the second half:你可以在下半场尝试这样的事情:

else {
        Node curr = head;
        Node prev = null;
        while(curr != null){                
            if(curr.id == id){
                curr.elems.add(elem);
                return this;
            }
            prev = curr;
            curr = curr.next;
        }
            Node node = new Node(id);
            node.elems.add(elem);
            prev.next = node;

        }
}

Your approach to finding a node with a matching ID will return a few different false negatives, which will in turn cause existing nodes to be overwritten.您查找具有匹配 ID 的节点的方法将返回一些不同的误报,这反过来会导致现有节点被覆盖。 The issue is that you're using a sliding window to inspect nodes and determine a match, but your criteria for sliding doesn't line up with your criteria for determining whether to append to an existing node or create a new node.问题是您正在使用滑动 window 来检查节点并确定匹配项,但您的滑动标准与您确定将 append 连接到现有节点还是创建新节点的标准不一致。

Here are a few examples to illustrate:下面举几个例子来说明:

  _ = null
  x = node
  o = node with matching ID
[ ] = sliding window (left side is `curr`, right side is `curr.next`)
x -> o -> _
[    ]

Since the matching node is at the end of the list, you should append
`elem` to it. However, your code checks `curr.id` (instead of `curr.next.id`),
incorrectly concludes that no matching node is found, and overwrites `curr.next`.
o -> x -> _
[    ]
     [    ]

Here, the matching node is at the head of the list, but your code
skips it and incorrectly creates a new node at the end of the list.
o -> x -> x -> _
[    ]
     [    ]
          [     ]
Same as above, a new node is incorrectly inserted at the end of
the list since you skipped the matching node at the head of the list.
x -> o -> x -> _
[    ]

Since you're checking `curr.id` (instead of `curr.next.id`), your code
incorrectly concludes that a new node needs to be created, overwriting
the existing (matching) node and truncating the tail of the list.

Linked lists are tough to reason about, and combining while conditions makes it even more difficult to grok.链表很难推理,而结合while条件则更难理解。 Here is a fixed implementation that (IMO) is easier to reason about:这是(IMO)更容易推理的固定实现:

public Place addElemToLst(String id, String elem) {
    // if the list is empty, create a new node
    if (head == null) {
        Node node = new Node(id);
        node.elems.add(elem);
        head = node;
        return this;
    }

    Node curr = head;
    while (curr.next != null) {
        // if the matching node appears inside the list,
        // append the element and return
        if (curr.id.equals(id)) {
            curr.elems.add(elem);
            return this;
        }

        curr = curr.next;
    }

    // if the last node in the list is a match, use it
    if (curr.id.equals(id)) {
        curr.elems.add(elem);
    // now that you've exhausted all nodes, create a new one
    } else {
        Node node = new Node(id);
        node.elems.add(elem);
        curr.next = node;
    }

    return this;
}

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

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