//返回 Object类型的数组
public Object[] toArray() {
Object[] r = new Object[size()];
Iterator<E> it = iterator();
for (int i = 0; i < r.length; i++) {
if (! it.hasNext())
//实现数组的复制,返回复制后的数组。
//参数是被复制的数组和复制的长度
//复制的长度大于被复制数组的长度,则填充类型默认值,String得默认值是null,int的默认值是0。
//新建一个原数组的拷贝,并修改原数组,指向这个新建数组。原数组自动抛弃(java垃圾回收机制会自动回收)。
return Arrays.copyOf(r, i);
r[i] = it.next();
}
//多余集合元素也保存到数组中
return it.hasNext() ? finishToArray(r, it) : r;
}
//剩余集合元素 保存到数组中
private static <T> T[] finishToArray(T[] r, Iterator<?> it) {
int i = r.length;
while (it.hasNext()) {
int cap = r.length;
//值得借鉴
//这是用来判断 数组r 是否需要进一步扩容
if (i == cap) {
//右移运算符,cap >> 1,相当于cap/2(取整)
//多加1,表示如果取整结果是0,避免扩容失败
//新的扩容大小newCap
int newCap = cap + (cap >> 1) + 1;
if (newCap - MAX_ARRAY_SIZE > 0)
newCap = hugeCapacity(cap + 1);
//因为数组新建之后,大小就不可以修改,
//所以通过这种方法扩容
r = Arrays.copyOf(r, newCap);
}
r[i++] = (T)it.next();
}
// 数组从0开始
return (i == r.length) ? r : Arrays.copyOf(r, i);
}
//整形类型是有范围的,最大值为Integer.MAX_VALUE,即2147483647,最小值为Integer.MIN_VALUE -2147483648。
public static final int MAX_VALUE = 0x7fffffff;
//来分配数组的size最大值。一些 VMs在数组里保留字头,试图分配更大数组时可能导致OutOfMemoryError:被请求数组的size超出VM界限。所以在数组中保留8
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
//判断数组容量是否溢出,最大为整型数据的最大值
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError
("Required array size too large");
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
另一个集合转成数组
//返回的类型与数组的类型相同
public <T> T[] toArray(T[] a) {
// 比较集合和已知数组的大小
//
int size = size();
T[] r = a.length >= size ? a :
(T[])java.lang.reflect.Array
.newInstance(a.getClass().getComponentType(), size);
//集合迭代器
Iterator<E> it = iterator();
//新数组的大小
for (int i = 0; i < r.length; i++) {
//因为有可能同步线程在修改这个集合,导致集合的元素减少
if (! it.hasNext()) {
//比较的是对象的引用
//即使集合的大小变小了,但是因为a.length在一开始就大于size()
if (a == r) {
//已知数组的大小 大于 集合的大小
//将新数组在 i 之后都置为 null
r[i] = null;
}
//这种情况是:刚开始a.length 是小于 size()
//但是由于同步的原因,导致集合size()变小。
//此时需要再比较一次 a.leng 和 实际size 的大小
//此时 i 可以认为是 实际集合size()大小
else if (a.length < i) {
return Arrays.copyOf(r, i);
} else {
//System提供了一个静态方法arraycopy(),我们可以使用它来实现数组之间的复制。(Object src,int srcPos,Object dest,int destPos,int length)。src:源数组; srcPos:源数组要复制的起始位置;dest:目的数组; destPos:目的数组放置的起始位置; length:复制的长度。src and dest都必须是同类型或者可以进行转换类型的数组.
System.arraycopy(r, 0, a, 0, i);
if (a.length > i) {
a[i] = null;
}
}
return a;
}
r[i] = (T)it.next();
}
// 可能会有同步添加元素,导致超出初始的数组大小
return it.hasNext() ? finishToArray(r, it) : r;
}
三、判断是否包含指定元素
public boolean contains(Object o) {
Iterator<E> it = iterator();
//判断参数是否为null
if (o==null) {
while (it.hasNext())
// 如果为null,则返回true,否则返回false
//使用 == 比较是否相等,如果用equals,会出现空指针异常
if (it.next()==null)
return true;
} else {
while (it.hasNext())
//使用equals比较两个对象,
if (o.equals(it.next()))
return true;
}
return false;
}
四、移除集合中的指定元素
//类似于contains()方法
public boolean remove(Object o) {
Iterator<E> it = iterator();
if (o==null) {
while (it.hasNext()) {
if (it.next()==null) {
it.remove();
return true;
}
}
} else {
while (it.hasNext()) {
if (o.equals(it.next())) {
it.remove();
return true;
}
}
}
return false;
}
五、判断参数集合中的元素是否在当前集合中
//ClassCastException异常:指定集合与当前集合中的一些元素类型不一致时,
//NullPointerException异常:指定集合包含null,但是当前集合不允许是null时,
public boolean containsAll(Collection<?> c) {
//遍历指定的集合
for (Object e : c)
//如果 指定的集合中有一个元素不在当前集合中,那么返回false
if (!contains(e))
return false;
//如果参数集合中所有的元素都在当前集合中,则返回true
return true;
}
六、添加指定集合中的所有元素
//如果指定的集合 也是当前集合本身 (自己给自己添加元素),那结果是不确定的。
public boolean addAll(Collection<? extends E> c) {
boolean modified = false;
for (E e : c)
//只要集合 c 中的任何一个元素成功添加到了当前集合中,即使其它元素全部添加失败了,此方法也会返回 true
if (add(e))
modified = true;
return modified;
}
七、移除所有与指定集合相同的元素
public boolean removeAll(Collection<?> c) {
boolean modified = false;
Iterator<?> it = iterator();
while (it.hasNext()) {
//只要当前集合中任何一个元素被移除,即使其它元素全部移除失败了,此方法也会返回 true
if (c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
八、移除当前集合中与指定集合不一致的元素
public boolean retainAll(Collection<?> c) {
boolean modified = false;
Iterator<E> it = iterator();
while (it.hasNext()) {
//指定的集合元素 不在 当前集合中,那么会被移除
//即使只有一个元素被移除,也会返回true.
if (!c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
九、清空集合
public void clear() {
Iterator<E> it = iterator();
while (it.hasNext()) {
it.next();
it.remove();
}
}
十、返回此 collection 的字符串表示形式
public String toString() {
Iterator<E> it = iterator();
//如果集合为空,返回[]
if (! it.hasNext())
return "[]";
//这些元素按其迭代器返回的顺序排列,并用方括号 ("[]") 括起来。相邻元素由字符 ", "(逗号加空格)分隔。
StringBuilder sb = new StringBuilder();
sb.append('[');
for (;;) {
E e = it.next();
sb.append(e == this ? "(this Collection)" : e);
if (! it.hasNext())
return sb.append(']').toString();
sb.append(',').append(' ');
}
}