简体   繁体   English

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

[英]Java ArrayList.remove() not decrementing the Size of the ArrayList

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(). 我有一个ArrayList来存储一些数据,但每当我从列表中删除一个项目时,即使我调用ArrayList.trimToSize(),大小也不会减少。 This is causing me nullPointerExceptions. 这导致我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. 我有一个名为_dataHeap的ArrayList和一个名为_dataMap的HashMap。 The ArrayList is a binary Heap containing a "findable" object, which has a Key. ArrayList是一个二进制Heap,包含一个“findable”对象,它有一个Key。 The HashMap bind from a Key to the index of the object in the ArrayList. HashMap从Key绑定到ArrayList中对象的索引。 This is so an item in the queue can be found by item using the HashMap or by index using ArrayList. 这样就可以通过使用HashMap的项目或使用ArrayList的索引找到队列中的项目。 The Key can be any Object, as long as it is unique for every item in the queue. Key可以是任何Object,只要它对队列中的每个项都是唯一的。

I've debugged this line by line, and the Heap contains the object, even down to the Hashcode. 我逐行调试了这个,而Heap包含了对象,甚至包含Hashcode。 The problem is, the Object is never being removed from the ArrayList. 问题是,Object永远不会从ArrayList中删除。 This must mean that _dataMap.get(element.getKey()) is not pointing to where it should. 这必须意味着_dataMap.get(element.getKey())没有指向它应该的位置。 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. 我已经检查了它,我在我的实现之外使用了一个测试对象,它从String映射到一个自定义对象,String作为键。

I make one object, with String "one" as its key. 我创建了一个对象,字符串“one”作为其键。 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. 它有相同的Hashcode,相同的Key,一切。 It gets removed from the map just fine, but not from the ArrayList. 它很好地从地图中删除,但不是从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. 我将_dataHeap.get(element.index)拉入其自己的变量中。 That solved EVERYTHING! 这解决了一切!

As Bemace said, check if remove works as you intend. 正如Bemace所说,检查删除是否按预期工作。 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. 我敢打赌,你正在编写的对象上的equals()方法不能按照你期望的方式工作,因为你没有覆盖它。

Furthermore, after you override equals, take care to also override hashCode. 此外,在重写equals之后,请注意也要覆盖hashCode。 It'll save you a SO question when your object doesn't work with HashMaps. 当您的对象无法使用HashMaps时,它会为您节省一些问题。 :) :)

A tip: Look into using JUnit . 提示:查看使用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. 很难忽视你漂亮的绿色酒吧上的鲜红色斑点。

Sounds to me like you're not actually removing anything. 听起来像你实际上并没有删除任何东西。 What's the return value of your remove call? remove电话的返回值是多少?

If you're using remove(int) the return value should be non-null. 如果您正在使用remove(int)则返回值应为非null。 If using remove(Object) , the result should be true. 如果使用remove(Object) ,则结果应为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 . 尝试删除不存在的元素不是错误,只返回nullfalse

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

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