今天想用LinkedList做一个消息推送的队列,
用到了remove方法,就很好奇,为啥remove以后上面取出的引用依然有值;
大概是这种
public T get() {
T last = queue.getLast();
queue.removeLast(); // 这里本身remove方法就返回被删除的元素,所以可以简化
return last;
}
就好奇看了一下为啥remove以后last变量的引用地址并没有失效,
于是看了下是怎么写 remove方法
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
// 一开始还不知道这个是啥意思,直到看明白他是复制数组来覆盖的,尝试模拟的时候写需要从哪里开始覆盖的时候写出了个ints.length-(delIndex+1)才反应过来
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;
}
哦,,原来不是把那个位置的元素的引用删除了,而是直接覆盖了这个引用,数组对于这个地址的引用直接不存在了,所以没有影响另一个我们取出的引用;关键点就在于这个
System.arraycopy
方法,接收5个参数按顺序分别为
1.
源数组;2.
源数组起点;3.
目标数组;4.
目标数组起点;5.
复制多少位;
这样只需要截取原数组需要删除的索引位置之后的所有元素,然后向前一位开始赋值,覆盖需要删除的索引位置就可以了,所以出现了size-index-1,就是长度回到原索引的时候多回一位;
Integer[] ints = new Integer[10];
for (int i = 0; i < 10; i++) {
ints[i] = i;
}
int delIndex = 3;
System.arraycopy(ints,delIndex+1,ints,delIndex,ints.length-delIndex-1);
ints[ints.length-1]=null;
System.out.println(Arrays.toString(ints));
睡觉!