我是靠谱客的博主 无辜冰淇淋,这篇文章主要介绍java源码分析---List类(JDK14),现在分享给大家,希望可以做个参考。


更多源码分析,请点击


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
2
public 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
14
default 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
10
default 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
2
E get(int index);

set(int, E)

将列表中指定索引 index 处的元素替换为 element

复制代码
1
2
E set(int index, E element);

add(int, E)

将指定的元素 element 插入此列表中的指定位置 index 。将当前在该位置的元素和后续元素右移。

复制代码
1
2
void add(int index, E element);

remove(int)

将列表中指定索引 index 处的元素删除,将该位置后的元素左移一位。

复制代码
1
2
E remove(int index);

indexOf(Object)

返回指定元素在列表中第一次出现的位置,如果没找到该元素,返回 -1。

复制代码
1
2
int indexOf(Object o);

lastIndexOf(Object)

返回指定元素在列表中最后一次出现的位置,如果没找到该元素,返回 -1。

复制代码
1
2
int lastIndexOf(Object o);

listIterator()

返回此列表的列表迭代器

复制代码
1
2
ListIterator<E> listIterator();

listIterator(int)

返回此列表的列表迭代器,从指定的索引位置开始。

复制代码
1
2
ListIterator<E> listIterator(int index);

subList(int, int)

将当前列表中区间 [fromIndex, toIndex) 中的元素作为一个新的列表返回。

复制代码
1
2
List<E> subList(int fromIndex, int toIndex);

of()

返回一个不可修改的不包含任何元素的空列表

复制代码
1
2
3
4
static <E> List<E> of() { return (List<E>) ImmutableCollections.ListN.EMPTY_LIST; }

直接返回 ImmutableCollections 类中的 EMPTY_LIST ,如下所示, EMPTY_LIST 在静态初始化块中被初始化为一个空的列表。

复制代码
1
2
3
4
5
6
7
8
static @Stable List<?> EMPTY_LIST; static { VM.initializeFromArchive(ListN.class); if (EMPTY_LIST == null) { EMPTY_LIST = new ListN<>(); } }

of(E)

返回一个不可修改的列表,列表中只包含一个元素 e1 。

复制代码
1
2
3
4
static <E> List<E> of(E e1) { return new ImmutableCollections.List12<>(e1); }

of(E, E)

返回一个不可修改的列表,列表中只包含两个元素 e1,e2 。

复制代码
1
2
3
4
static <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
16
static 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
4
static <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
15
static <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
4
static <E> List<E> copyOf(Collection<? extends E> coll) { return ImmutableCollections.listCopy(coll); }

如果参数 collAbstractImmutableList 的子类并且不是 SubList 类,直接将 coll 转换为 List 返回。

否则,将列表 coll 先转换为数组,再调用 List.of() 方法实现。

复制代码
1
2
3
4
5
6
7
8
static <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)内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(133)

评论列表共有 0 条评论

立即
投稿
返回
顶部