package com.company;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* ArrayList的四中初始化方法
*/
public class Main {
public static void main(String[] args) {
// 第一种使用使用Arrays.asList
List<String> strs = new ArrayList<>(Arrays.asList("1","2","3"));
//第二种使用生成匿名内部类
List<String> strs1 = new ArrayList<String>(){{
add("1");
add("2");
add("3");
}
};
//最常见的一种初始化方法,看起来不够优美,low
List<String> strs2 = new ArrayList<>();
strs2.add("1");
strs2.add("2");
strs2.add("3");
//使用Collections.nCopies,例子中会输出5个1;
List<String> strs3 = new ArrayList<>(Collections.nCopies(5,"1"));
for (String str3:strs3){
System.out.println(str3);
}
}
}
二、ArrayList.remove()避坑
场景:按照条件删除list中的元素.
1、fori循环中调用ArrayList.remove(i)
package com.ysy.集合类;
import java.util.ArrayList;
import java.util.List;
/**
* @author
* @date 2020/9/3
*/
public class TestArrayList {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("2");
list.add("4");
for (int i = 0; i < list.size(); i++) {
String str = list.get(i);
if (str.equals("2")) {
list.remove(i);
}
}
System.out.println(list);
}
}
结果:
解决方法:
list.remove(i);//后面添加i–
i–;
2、iterator遍历过程中或者增强for循环(底层就是iterator遍历)调用ArrayList.remove()
package com.ysy.集合类;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @author shanyangyang
* @date 2020/9/3
*/
public class TestArrayList {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("2");
list.add("4");
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String str = it.next();
if (str.equals("2")) {
list.remove(str);
}
}
System.out.println(list);
}
}
结果:
解决:
list.remove(str); //修改为
it.remove();
3、ArrayList.remove()源码分析
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
主要调用了fastremove方法;
modCount++:每次修改都递增1;然后把数组copy一份,组成删除后数组;
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
}
ArrayList的内部类Itr继承Iterator,Itr内部有个expectedModCount,如果expectedModCount和modCount不相等就会抛出异常。
private class Itr implements Iterator<E> {
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
下面看看 it.remove();方法的源码:
进行了如下的赋值操作,避免了CME异常
expectedModCount = modCount;
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}