JDK-In-Action-ArrayList
ArrayList
List
接口的具体实现,底层基于Object[]
存储元素,可自动扩容,元素可为null
,非线程安全.
优势:随机访问操作只需常量时间;
劣势:随机插入,随机删除,新增大量元素的操作需要线性时间;
API Example
元素替换和查找
List<Integer> data = new ArrayList<>(Arrays.asList(1, 2, 2, 2, 5));
data.set(1, 0);
assertEquals(data, "[1, 0, 2, 2, 5]");
int i = data.indexOf(2);
assertEquals(i, 2);
i = data.lastIndexOf(2);
assertEquals(i, 3);
boolean contains = data.contains(2);
assertTrue(contains);
contains = data.contains(3);
assertTrue(!contains);
contains = data.containsAll(Arrays.asList(2, 5));
assertTrue(contains);
指定容量的构造函数
List<String> initCapacityList = new ArrayList<>(2);
assertEquals(initCapacityList, "[]");
静态构造不可变的 List
//java.util.Arrays.ArrayList
List<String> list = Arrays.asList("one", "two");
try {
list.add("three");
assertFail();
} catch (UnsupportedOperationException e) {
e.printStackTrace(System.out);
}
java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at com.gitee.zhwcong.collections.ArrayListExample.静态构造不可变的List(ArrayListExample.java:44)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.gitee.zhwcong.Utils.runExampleMethod(Utils.java:41)
at com.gitee.zhwcong.collections.ArrayListExample.main(ArrayListExample.java:15)
新增和插入元素
List<String> data = new ArrayList<>();
//新增
data.add("one");
data.addAll(Arrays.asList("three", "four"));
//插入
data.add(0, "zero");
data.add(1, "two");
assertEquals(data, "[zero, two, one, three, four]");
//批量插入
data.addAll(4, Arrays.asList("five", "six"));
assertEquals(data, "[zero, two, one, three, five, six, four]");
删除和清空列表
List<Integer> data = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
data.remove(0);
assertEquals(data, "[2, 3, 4, 5]");
data.remove(3);
assertEquals(data, "[2, 3, 4]");
data.clear();
assertEquals(data, "[]");
指定初始集合的构造函数
Collection<String> data = new ArrayList<>();
data.add("one");
List<String> initDataList = new ArrayList<>(data);
assertEquals(initDataList, "[one]");
单线程中的并发修改异常
List<Integer> list = new ArrayList<>();
list.addAll(Arrays.asList(1, 2, 3, 4, 5));
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
Integer next = iterator.next();
iterator.remove();
//这里任何对list的更新都会导致`ConcurrentModificationException`
// list.remove(next);
// list.add(1);
}
复制所有元素到对象数组
List<Integer> data = Arrays.asList(1, 2, 3, 4, 5);
Object[] objects = data.toArray();
assertEquals(objects, "[1, 2, 3, 4, 5]");
复制所有元素到整数类型数组
List<Integer> data = Arrays.asList(1, 2, 3, 4, 5);
Integer[] a = new Integer[0];
Integer[] ints = data.toArray(a);
assertEquals(ints, "[1, 2, 3, 4, 5]");
assertTrue(a.length == 0);
//仅当参数数组的空间足够拷贝所有元素时参数a才会被填充值
a = new Integer[data.size()];
ints = data.toArray(a);
assertEquals(a, "[1, 2, 3, 4, 5]");
assertEquals(ints, "[1, 2, 3, 4, 5]");
空构造函数
List<String> emptyList = new ArrayList<>();
assertEquals(emptyList, "[]");
列表排序
List<Integer> data = new ArrayList<>(Arrays.asList(9, 2, 7, 3, 1));
System.out.println("自然顺序");
Collections.sort(data);
assertEquals(data, "[1, 2, 3, 7, 9]");
System.out.println("逆序");
Collections.sort(data, (o1, o2) -> o2 - o1);
assertEquals(data, "[9, 7, 3, 2, 1]");
自然顺序
逆序
For循环迭代元素
List<Integer> data = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
for (int i = 0; i < data.size(); i++) {
System.out.println(data.get(i));
}
1
2
3
4
5
Foreach Stream迭代元素
List<Integer> data = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
data.forEach(System.out::println);
1
2
3
4
5
List Iterator迭代元素
List<Integer> data = new ArrayList<>(Arrays.asList(1, 2, 3));
ListIterator<Integer> listIterator = data.listIterator();
System.out.println("next is 1:" + listIterator.next());
listIterator.add(5);
assertEquals(data, "[1, 5, 2, 3]");
System.out.println("next is 2:" + listIterator.next());
System.out.println("previous is 2:" + listIterator.previous());
listIterator.remove();
assertEquals(data, "[1, 5, 3]");
next is 1:1
next is 2:2
previous is 2:2
Foreach迭代元素
List<Integer> data = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
for (Integer e : data) {
System.out.println(e);
}
1
2
3
4
5
Iterator迭代元素
List<Integer> data = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
Iterator<Integer> iterator = data.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
1
2
3
4
5
列表切片视图
List<Integer> data = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
System.out.println("生成一个共享底层数组的视图");
List<Integer> subList = data.subList(1, 4);
assertEquals(subList, "[2, 3, 4]");
subList.add(6);
assertEquals(subList, "[2, 3, 4, 6]");
assertEquals(data, "[1, 2, 3, 4, 6, 5]");
生成一个共享底层数组的视图
引用
- 示例源码下载
- JDK8
java.util.ArrayList
Source Code