java-集合arraylist
阿新 • • 發佈:2018-11-08
坑點
做題常用:
- 陣列轉變
Arraylist.asList() 實際上傳的是一個可變長引數,呼叫了內部類,基礎型別的陣列由於
不是封裝類(猜測java對封裝型別的陣列和變長引數有過轉換處理,形如scala隱式抓換),導致基本型別陣列,在<>中只能被定義為 陣列型別;
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
private static final long serialVersionUID = -2764017481108945198L;
private final E[] a;
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
@Override
public int size() {
return a.length;
}
@Override
public Object[] toArray() {
return a.clone();
}
}
- remove
最好不要在迴圈體中使用remove效率極其低下,每次都會產生一個新的list,由於gc優先順序很低,會導致潛在的記憶體溢位
/*
* Private remove method that skips bounds checking and does not
* return the value removed.
*/
private void fastRemove(int index) {
modCount++;
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
}
推薦使用:
private boolean batchRemove(Collection<?> c, boolean complement) {
final Object[] elementData = this.elementData;
int r = 0, w = 0;
boolean modified = false;
try {
for (; r < size; r++)
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];
} finally {
// Preserve behavioral compatibility with AbstractCollection,
// even if c.contains() throws.
if (r != size) {
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;
}
if (w != size) {
// clear to let GC do its work
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}
這段程式碼只生成了一次陣列,缺點是必須要轉成set或者list,基本型別需要包裝一次
缺點:如果是char(2byte)、int(4byte)等基本型別,包裝過後需要一個引用4個位元組,object物件8個位元組,最小是12個位元組還不包含內容;使得記憶體佔用變大;