更多源码分析,请点击
List
List接口:存储有序的,可重复的数据。 --> “动态”数组
-
ArrayList、LinkedList、Vector
同:三个类都实现了List接口,存储数据的特点相同:存储有序的、可重复的数据;
异:ArrayList线程不安全,效率高;Vector线程安全,效率低,底层使用Object[]存储
LinkedList底层使用双向链表存储,对于频繁的插入、删除操作,效率较高;
(1)ArrayList 本质上是一个可改变大小的数组.当元素加入时,其大小将会动态地增长.内部的元素可以直接通过get与set方法进行访问.元素顺序存储 ,随机访问很快,删除非头尾元素慢,新增元素慢而且费资源 ,较适用于无频繁增删的情况 ,比数组效率低,如果不是需要可变数组,可考虑使用数组 ,非线程安全.
(2)LinkedList 是一个双链表,在添加和删除元素时具有比ArrayList更好的性能.但在get与set方面弱于ArrayList. 适用于 :没有大规模的随机读取,有大量的增加/删除操作.随机访问很慢,增删操作很快,不耗费多余资源 ,允许null元素,非线程安全.
(3)Vector (类似于ArrayList)但其是同步的,开销就比ArrayList要大。如果你的程序本身是线程安全的,那么使用ArrayList是更好的选择。 Vector和ArrayList在更多元素添加进来时会请求更大的空间。Vector每次请求其大小的双倍空间,而ArrayList每次对size增长50%.
1
2public interface List<E> extends Collection<E>
List 接口继承自 Collection 接口,故包含了 Collection 类中所有的方法,这里不再接口,点击查看 Collection 类的分析
replaceAll(UnaryOperator<E> operator)
将当前列表中的每个元素替换为operator操作后的结果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14default void replaceAll(UnaryOperator<E> operator) { Objects.requireNonNull(operator); final ListIterator<E> li = this.listIterator(); while (li.hasNext()) { li.set(operator.apply(li.next())); } } //例: @Test public void test(){ List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); list.replaceAll(i -> i + 1); //结果为:list = {2, 3, 4, 5, 6} }
分析 :
-
UnaryOperator<T> 接口继承自 Function<T, T> 接口。是一个函数式接口,表示对单个操作数的操作,该操作产生与其操作数相同类型的结果。
-
对列表中每个元素进行 operator 操作,然后用所得到的结果替换原来的元素。
-
对每个元素的操作通过调用 apply 方法进行,该方法再 Function<T, T> 中声明。调用时传递的参数即为对 apply 方法的重写。
sort(Comparator<? super E> c)
根据指定的规则对列表进行排序。
分析 :
- 先将列表转为数组,然后调用数组的 sort 方法使用给定规则对数组进行排序
- 将排好序的数组中每个元素依次加入到列表中。
1
2
3
4
5
6
7
8
9
10default void sort(Comparator<? super E> c) { Object[] a = this.toArray(); Arrays.sort(a, (Comparator) c); ListIterator<E> i = this.listIterator(); for (Object e : a) { i.next(); i.set((E) e); } }
get(int)
返回当前列表中索引 index 处的元素
1
2E get(int index);
set(int, E)
将列表中指定索引 index 处的元素替换为 element 。
1
2E set(int index, E element);
add(int, E)
将指定的元素 element 插入此列表中的指定位置 index 。将当前在该位置的元素和后续元素右移。
1
2void add(int index, E element);
remove(int)
将列表中指定索引 index 处的元素删除,将该位置后的元素左移一位。
1
2E remove(int index);
indexOf(Object)
返回指定元素在列表中第一次出现的位置,如果没找到该元素,返回 -1。
1
2int indexOf(Object o);
lastIndexOf(Object)
返回指定元素在列表中最后一次出现的位置,如果没找到该元素,返回 -1。
1
2int lastIndexOf(Object o);
listIterator()
返回此列表的列表迭代器
1
2ListIterator<E> listIterator();
listIterator(int)
返回此列表的列表迭代器,从指定的索引位置开始。
1
2ListIterator<E> listIterator(int index);
subList(int, int)
将当前列表中区间 [fromIndex, toIndex) 中的元素作为一个新的列表返回。
1
2List<E> subList(int fromIndex, int toIndex);
of()
返回一个不可修改的不包含任何元素的空列表
1
2
3
4static <E> List<E> of() { return (List<E>) ImmutableCollections.ListN.EMPTY_LIST; }
直接返回 ImmutableCollections 类中的 EMPTY_LIST ,如下所示, EMPTY_LIST 在静态初始化块中被初始化为一个空的列表。
1
2
3
4
5
6
7
8static @Stable List<?> EMPTY_LIST; static { VM.initializeFromArchive(ListN.class); if (EMPTY_LIST == null) { EMPTY_LIST = new ListN<>(); } }
of(E)
返回一个不可修改的列表,列表中只包含一个元素 e1 。
1
2
3
4static <E> List<E> of(E e1) { return new ImmutableCollections.List12<>(e1); }
of(E, E)
返回一个不可修改的列表,列表中只包含两个元素 e1,e2 。
1
2
3
4static <E> List<E> of(E e1, E e2) { return new ImmutableCollections.List12<>(e1, e2); }
上述两个方法 of(E) 、 of(E, E) 都是通过掉用 List12 类的构造方法实现,如下所示,当所传参数不为空时,直接将参数赋值给列表中的元素。 List12 类的对象最多只能包含两个元素。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16static final class List12<E> extends AbstractImmutableList<E> implements Serializable { @Stable private final E e0; @Stable private final E e1; List12(E e0) { this.e0 = Objects.requireNonNull(e0); this.e1 = null; } List12(E e0, E e1) { this.e0 = Objects.requireNonNull(e0); this.e1 = Objects.requireNonNull(e1); } }
of(E, E, E)
返回一个不可修改的列表,列表中只包含三个元素 e1,e2,e3 。
1
2
3
4static <E> List<E> of(E e1, E e2, E e3) { return new ImmutableCollections.ListN<>(e1, e2, e3); }
of(E, E, E) 、of(E, E, E, E) 、…… 、of(E, E, E, E, E, E, E, E, E, E) 等方法原理一致,均是调用 ListN 的构造方法实现,将参数中的元素添加到elements数组中。
1
2
3
4
5
6
7
8
9
10
11
12
13@Stable private final E[] elements; @SafeVarargs ListN(E... input) { // copy and check manually to avoid TOCTOU @SuppressWarnings("unchecked") E[] tmp = (E[])new Object[input.length]; // implicit nullcheck of input for (int i = 0; i < input.length; i++) { tmp[i] = Objects.requireNonNull(input[i]); } elements = tmp; }
of(E…)
返回一个不可修改的列表,列表中的元素个数为 elements.length 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15static <E> List<E> of(E... elements) { switch (elements.length) { // implicit null check of elements case 0: @SuppressWarnings("unchecked") var list = (List<E>) ImmutableCollections.ListN.EMPTY_LIST; return list; case 1: return new ImmutableCollections.List12<>(elements[0]); case 2: return new ImmutableCollections.List12<>(elements[0], elements[1]); default: return new ImmutableCollections.ListN<>(elements); } }
copyOf(Collection<? extend E> coll)
将 coll 拷贝一份返回新的列表,该列表不可修改。
1
2
3
4static <E> List<E> copyOf(Collection<? extends E> coll) { return ImmutableCollections.listCopy(coll); }
如果参数 coll 是 AbstractImmutableList 的子类并且不是 SubList 类,直接将 coll 转换为 List 返回。
否则,将列表 coll 先转换为数组,再调用 List.of() 方法实现。
1
2
3
4
5
6
7
8static <E> List<E> listCopy(Collection<? extends E> coll) { if (coll instanceof AbstractImmutableList && coll.getClass() != SubList.class) { return (List<E>)coll; } else { return (List<E>)List.of(coll.toArray()); } }
更多源码分析,请点击
最后
以上就是无辜冰淇淋最近收集整理的关于java源码分析---List类(JDK14)的全部内容,更多相关java源码分析---List类(JDK14)内容请搜索靠谱客的其他文章。
发表评论 取消回复