Java ArrayList.remove() 不减少 ArrayList 的大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3963652/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 04:11:03  来源:igfitidea点击:

Java ArrayList.remove() not decrementing the Size of the ArrayList

javaarrayssizearraylist

提问by digiholic

I have an ArrayList to store some data, but whenever I remove an item from the list, the size does not decrease, even when I call ArrayList.trimToSize(). This is causing me nullPointerExceptions.

我有一个 ArrayList 来存储一些数据,但是每当我从列表中删除一个项目时,即使我调用 ArrayList.trimToSize(),它的大小也不会减小。这导致我 nullPointerExceptions。

How can I remove a single item from an ArrayList and have the list's size() shrink accordingly?

如何从 ArrayList 中删除单个项目并相应地缩小列表的 size() ?

EDIT: All right, here's the code. Here's a bit of background you'll need to know, since I can't post all the code. I have an ArrayList called _dataHeap and a HashMap called _dataMap. The ArrayList is a binary Heap containing a "findable" object, which has a Key. The HashMap bind from a Key to the index of the object in the ArrayList. This is so an item in the queue can be found by item using the HashMap or by index using ArrayList. The Key can be any Object, as long as it is unique for every item in the queue.

编辑:好的,这是代码。这是您需要了解的一些背景知识,因为我无法发布所有代码。我有一个名为 _dataHeap 的 ArrayList 和一个名为 _dataMap 的 HashMap。ArrayList 是一个二进制堆,包含一个“可查找”对象,它有一个键。HashMap 从 Key 绑定到 ArrayList 中对象的索引。这样就可以使用 HashMap 按项目或使用 ArrayList 的索引找到队列中的项目。Key 可以是任何对象,只要它对队列中的每个项目都是唯一的。

I've debugged this line by line, and the Heap contains the object, even down to the Hashcode. The problem is, the Object is never being removed from the ArrayList. This must mean that _dataMap.get(element.getKey()) is not pointing to where it should. I've checked it though, I used a test object outside of my implementation that maps from a String to a custom object with String as a Key.

我一行一行地调试了这个,堆包含对象,甚至到哈希码。问题是,对象永远不会从 ArrayList 中删除。这一定意味着 _dataMap.get(element.getKey()) 没有指向它应该指向的位置。不过我已经检查过了,我在我的实现之外使用了一个测试对象,该对象从一个字符串映射到一个以字符串为键的自定义对象。

I make one object, with String "one" as its key. I insert it, then try to remove it. I've stepped through this, and everything checks out, except one thing: The object is never removed from the queue. It's got the same Hashcode, the same Key, everything. It gets removed from the map just fine, but not from the ArrayList.

我制作了一个对象,以字符串“one”为键。我插入它,然后尝试删除它。我已经完成了这个,一切都检查出来了,除了一件事:对象永远不会从队列中删除。它有相同的哈希码,相同的密钥,一切。它可以很好地从地图中删除,但不能从 ArrayList 中删除。

Here's the remove method:

这是删除方法:

public T remove(T element) {
    //We'll need this data to return the proper value
    T t = _dataHeap.get(_dataMap.get(element.getKey()));
    /*
     * this Swap() call is used to swap our target with the end
     * of the arraylist. This means that whenever we remove it,
     * we don't have a change in indexes of the other nodes.
     * After that, we downHeapify() to fix the whole graph back
     * to it's functional state.
     */
    swap(_dataMap.get(element.getKey()),length()-1);
    //Remove from the Heap
    _dataHeap.remove(_dataMap.get(element.getKey()));
    _dataHeap.trimToSize();
    //Remove from the Map
    _dataMap.remove(element.getKey());
    downHeapify();
    return t;

I hope this gives you a better idea of what I'm doing wrong.

我希望这能让你更好地了解我做错了什么。

EDIT THE SECOND: Holy crap I finally fixed it! I pulled the _dataHeap.get(element.index) into it's own variable. That solved EVERYTHING!

编辑第二个:天哪,我终于修好了!我将 _dataHeap.get(element.index) 拉入它自己的变量中。这解决了一切!

回答by Mike

As Bemace said, check if remove works as you intend. I'd bet money that your equals() method on the object you're composing doesn't work how you'd expect it to, because you did not override it.

正如 Bemace 所说,检查 remove 是否按您的意图工作。我敢打赌,你正在编写的对象上的 equals() 方法不会像你期望的那样工作,因为你没有覆盖它。

Furthermore, after you override equals, take care to also override hashCode. It'll save you a SO question when your object doesn't work with HashMaps. :)

此外,在覆盖 equals 之后,还要注意覆盖 hashCode。当您的对象不适用于 HashMap 时,它会为您省去一个 SO 问题。:)

A tip: Look into using JUnit. It will blow these little errors right out of the water, making it obvious to you when something's not working how you'd hope. It's very hard to ignore a bright red spot on your beautiful green bar.

提示:考虑使用JUnit。它会将这些小错误一扫而空,当某些事情没有按照您希望的方式工作时,您会很清楚。很难忽略美丽的绿色条上的鲜红色斑点。

回答by Brad Mace

Sounds to me like you're not actually removing anything. What's the return value of your removecall?

在我看来,您实际上并没有删除任何东西。你remove调用的返回值是多少?

If you're using remove(int)the return value should be non-null. If using remove(Object), the result should be true. Otherwise you haven't actually removed anything. Attempting to remove an element which doesn't exist is not an error, just returns nullor false.

如果您正在使用remove(int)返回值应该是非空的。如果使用remove(Object),结果应该是真的。否则你实际上并没有删除任何东西。尝试删除不存在的元素不是错误,只是返回nullfalse