2017-07-31 100 views
0

我试图忽略从ArrayBuffer中删除元素是如何工作的。下面是它:了解Scala中的ArrayBuffer

override def remove(n: Int, count: Int) { 
    if (count < 0) throw new IllegalArgumentException("removing negative number of elements: " + count.toString) 
    else if (count == 0) return // Did nothing 
    if (n < 0 || n > size0 - count) throw new IndexOutOfBoundsException("at " + n.toString + " deleting " + count.toString) 
    copy(n + count, n, size0 - (n + count)) 
    reduceToSize(size0 - count) 
    } 

的事情是如下副本实现:

protected def copy(m: Int, n: Int, len: Int) { 
    scala.compat.Platform.arraycopy(array, m, array, n, len) 
} 

这意味着它只是复制新阵列的同一个数组内容而不调整其大小。相比之下,ArrayListJDK中调整了数组的大小,只要我们从中删除元素即可。

我的理解错在哪里?

回答

1

reduceToSize方法减少了我认为数组的大小。

def reduceToSize(sz: Int) { 
    require(sz <= size0) 
    while (size0 > sz) { 
     size0 -= 1 
     array(size0) = null 
    } 
    } 
+0

不太清楚。如果我们将null设置为用新大小重新创建数组,它是否完全相同? –

+0

@ St.Antario重新创建阵列要贵得多,因此只需将元素设置为null,并使GC可以完成其工作就更合适。我们并不关心内部数组的实际大小,而是私有字段'size0'的值。 – aristotll

1

对于的JavaArrayList也没有收缩数据阵列,只需设置null去除元素GC他们。 斯卡拉ArrayBuffer做几乎同样的事情ArrayList

public E remove(int index) { 
    rangeCheck(index); 

    modCount++; 
    E oldValue = elementData(index); 

    int numMoved = size - index - 1; 
    if (numMoved > 0) 
     System.arraycopy(elementData, index+1, elementData, index, 
         numMoved); 
    elementData[--size] = null; // clear to let GC do its work 

    return oldValue; 
} 
+0

所以这意味着我们实际上有一个相同大小的数组,但是将元素设置为null,对吧? –

+0

是的,也许这个帖子对你很有帮助:https://stackoverflow.com/questions/41933700/why-java-arraylists-do-not-shrink-automatically – chengpohi