要点
1.ArrayList底层实现是一个数组,每次新增或删除元素时,基本都要重新排列一次元素,查询的时候可以直接根据索引进行查询;LinkedList是一个双向链表,插入和删除的时候不需要重新排列元素,查询的时候需要从第一个节点或最后一个节点依次查找。因此,插入和删除元素,LinkedList效率高,查找元素ArrayList效率高,要使用哪一种要看插入删除多还是查询多。
2.ArrayList是非线程安全的,Vector是一个线程安全的ArrayList,但因为要synchronized,所以效率会很低。
下面代码测试了线程安全的问题:
import java.util.ArrayList;
import java.util.List;
public class TestArrayList {
public static void main(String[] args) {
testArrayList();
}
static int endThread = 0;
public static void testArrayList() {
List<Person> persons = new ArrayList<Person>();// 非线程安全,会报异常
// List<Person> persons = new Vector<Person>();// 线程安全,长度大小正确
// List<Person> persons = new LinkedList<Person>();// 非线程安全,长度大小不正确
Object lock = new Object();
for (int i = 0; i < 10; i++) {
new Thread(() -> {
for (int j = 0; j < 30; j++) {
persons.add(new Person("墨倾池"));
}
synchronized (lock) {
endThread++;
if (endThread == 10) {
lock.notify();
System.out.println("唤醒主线程");
}
}
}).start();
}
try {
synchronized (lock) {
System.out.println("主线程阻塞");
lock.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
int size = persons.size();
System.out.println("长度大小" + size);
for (int i = 1; i < size + 1; i++) {
System.out.print(persons.get(i - 1));
if (i % 50 == 0) {
System.out.println();
}
}
}
private static class Person {
String name;
Person(String name) {
this.name = name;
}
}
}