Collection(集合)
常用方法
可以发现,List比Set多很多的方法
retainAll
这个方法的意思就是去两个集合的交集,返回的结果就是值是否被修改,下边是ArrayList的源码
public boolean retainAll(Collection<?> c) {
Objects.requireNonNull(c);
return batchRemove(c, true);
}
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;
}
subList
从开始下标截取的指定的下标(注意不包含toIndex)
List<E> subList(int fromIndex, int toIndex);
containsAll
集合A是否完全包含集合B,对之对应的还有contains,是否包含某个元素,内部用的equal()
List<String> list= Arrays.asList("1","2","3","4","5");
//true
System.out.println(list.containsAll(Arrays.asList("1","2")));
//false
System.out.println(list.containsAll(Arrays.asList("1","6")));
其他的就不写了。。。太多了。
ArrayList和Vector
1.线程安全
Vector是线程安全的,而ArrayList是非线程安全的。原因:通过看源码,会发现Vector的add,addAll等方法在方
法名称用了synchronized(也就是this锁),所有导致ArrayList效率更高。
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
2.内存方面
在构造方法没有指定initialCapacity(初始化空间)的情况下,Vector默认为10(ArrayList放数据的时候,最开始才默认为10),
而ArrayList不设置initialCapacity,默认是0,无参的构造方法如下:
public Vector() {
this(10);
}
public ArrayList() {
//其中DEFAULTCAPACITY_EMPTY_ELEMENTDATA为{}
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
当capacity小于size的时候,都会调用grow方法进行扩容,代码如下,可以发现没有指定capacityIncrement(当空间不足的时候,每次需要扩容的大小),Vetor是直接扩容一倍,而ArrayList是0.5倍,可以看出在默认的构造方法的情况下,ArrayList更节约内存。
//ArrayList,其中minCapacity为开始的size加上需要添加数据的size
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
//Vetor
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
ArrayList和LinkedArrayList
Map
解决HashTable过慢的方法->ConcurrentMap
12. 【推荐】高度注意 Map 类集合 K/V 能不能存储 null 值的情况,如下表格:
集合类 Key Value Super 说明
Hashtable 不允许为 null 不允许为 null Dictionary 线程安全
ConcurrentHashMap 不允许为 null 不允许为 null AbstractMap 锁分段技术(JDK8:CAS)
TreeMap 不允许为 null 允许为 null AbstractMap 线程不安全
HashMap 允许为 null 允许为 null AbstractMap 线程不安全
反例: 由于 HashMap 的干扰,很多人认为 ConcurrentHashMap 是可以置入 null 值,而事实上, 存储 null 值时会抛出 NPE 异常