Java ArrayList.remove() 不减少 ArrayList 的大小
我有一个 ArrayList 来存储一些数据,但是每当我从列表中删除一个项目时,即使我调用 ArrayList.trimToSize(),大小也不会减小。这导致我出现 nullPointerExceptions。
如何从 ArrayList 中删除单个项目并使列表的 size() 相应缩小?
编辑:好的,这是代码。这是您需要了解的一些背景知识,因为我无法发布所有代码。我有一个名为 _dataHeap 的 ArrayList 和一个名为 _dataMap 的 HashMap。 ArrayList 是一个包含“可查找”对象的二进制堆,该对象有一个 Key。 HashMap 将 Key 绑定到 ArrayList 中对象的索引。这样就可以使用 HashMap 按项目或使用 ArrayList 按索引找到队列中的项目。 Key 可以是任何对象,只要它对于队列中的每个项目都是唯一的。
我已经逐行调试了该对象,并且堆包含该对象,甚至包含哈希码。问题是,该对象永远不会从 ArrayList 中删除。这必定意味着 _dataMap.get(element.getKey()) 没有指向它应该指向的位置。我已经检查过了,我在实现之外使用了一个测试对象,该对象从字符串映射到以字符串作为键的自定义对象。
我创建一个对象,以字符串“one”作为其键。我插入它,然后尝试将其移除。我已经完成了这个过程,一切都检查完毕,除了一件事:该对象永远不会从队列中删除。它有相同的哈希码,相同的密钥,一切。它可以很好地从地图中删除,但不能从 ArrayList 中删除。
这是删除方法:
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;
我希望这能让您更好地了解我做错了什么。
编辑第二个:天哪,我终于修好了!我将 _dataHeap.get(element.index) 拉入它自己的变量中。这解决了一切!
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.
How can I remove a single item from an ArrayList and have the list's size() shrink accordingly?
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.
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.
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.
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如 Bemace 所说,检查删除是否按您的预期工作。我敢打赌,您正在编写的对象上的 equals() 方法不会按您期望的方式工作,因为您没有覆盖它。
此外,在覆盖 equals 后,请注意也覆盖 hashCode。当你的对象不能与 HashMap 一起使用时,它会为你省去一个问题。 :)
提示:研究使用 JUnit。它会将这些小错误从水中剔除,让您在某些事情没有按照您希望的方式工作时显而易见。很难忽视美丽的绿色条上的亮红点。
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.
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. :)
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.
在我看来,你实际上并没有删除任何东西。
remove
调用的返回值是多少?如果您使用
remove(int)
,则返回值应为非空。如果使用remove(Object)
,结果应该为 true。否则你实际上并没有删除任何东西。尝试删除不存在的元素不是错误,只是返回 null 或 false。Sounds to me like you're not actually removing anything. What's the return value of your
remove
call?If you're using
remove(int)
the return value should be non-null. If usingremove(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 null or false.