您的位置:首页 > 财经 > 金融 > 新媒体配图的相关知识_哈尔滨造价信息网官网_企业培训公司_免费下载b站视频软件

新媒体配图的相关知识_哈尔滨造价信息网官网_企业培训公司_免费下载b站视频软件

2024/12/28 13:01:03 来源:https://blog.csdn.net/q68686/article/details/144720269  浏览:    关键词:新媒体配图的相关知识_哈尔滨造价信息网官网_企业培训公司_免费下载b站视频软件
新媒体配图的相关知识_哈尔滨造价信息网官网_企业培训公司_免费下载b站视频软件

List 是 Java 中最常用的数据结构之一,广泛用于存储有序的元素集合。它是 Java 集合框架中的一个接口,提供了多种常见的实现,如 ArrayListLinkedListVector 等。通过对 List 接口及其常见实现类的源码分析,开发者可以深入理解其内部机制和实现方式,进而优化应用程序的性能,做出更合适的选择。

本文将通过深入解析 List 接口及其常见实现(特别是 ArrayList 和 LinkedList)的源码,帮助开发者全面理解 Java 中 List 的实现原理和使用场景。

1. List 接口概述

在 Java 集合框架中,List 是一个有序的集合接口,表示一个元素序列,允许重复元素。与 Set 不同,List 允许按照插入顺序访问元素,并提供了元素插入和删除的灵活操作。

List 接口声明如下:

public interface List<E> extends Collection<E> {boolean add(E e);void add(int index, E element);E get(int index);E remove(int index);boolean contains(Object o);int size();Iterator<E> iterator();ListIterator<E> listIterator();List<E> subList(int fromIndex, int toIndex);
}

1.1 List 接口常用方法

  • add(E e):添加元素到列表的尾部。
  • get(int index):根据索引获取指定位置的元素。
  • remove(int index):根据索引移除指定位置的元素。
  • contains(Object o):检查列表是否包含指定元素。
  • size():返回列表中元素的个数。
  • subList(int fromIndex, int toIndex):返回从 fromIndex 到 toIndex 范围的子列表。

2. ArrayList 实现解析

ArrayList 是 List 接口的一个常见实现,底层基于动态数组实现,允许快速随机访问,但在插入和删除元素时性能较差,特别是在数组中间插入或删除时。

2.1 ArrayList 类结构

ArrayList 类的关键字段如下:

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {private static final int DEFAULT_CAPACITY = 10;transient Object[] elementData;private int size;public ArrayList() {this.elementData = new Object[DEFAULT_CAPACITY];}public ArrayList(int initialCapacity) {if (initialCapacity > 0) {this.elementData = new Object[initialCapacity];} else {this.elementData = new Object[DEFAULT_CAPACITY];}}public boolean add(E e) {ensureCapacity(size + 1);  // 保证容量足够elementData[size++] = e;return true;}public E get(int index) {rangeCheck(index);  // 检查索引是否越界return (E) elementData[index];}public int size() {return size;}
}

展开

2.2 elementData 数组

ArrayList 底层是通过一个 Object[] elementData 数组来存储元素。这个数组的容量是动态变化的,默认容量为 10,当元素数量超过当前容量时,ArrayList 会自动增加容量,通常是扩展为原来容量的 1.5 倍。

2.3 add(E e) 方法

add 方法用于向 ArrayList 中添加元素。为了确保数组容量足够,add 方法会先调用 ensureCapacity 方法检查当前容量。如果当前容量不足以容纳新增元素,就会扩展容量。

private void ensureCapacity(int minCapacity) {int oldCapacity = elementData.length;if (minCapacity > oldCapacity) {int newCapacity = oldCapacity + (oldCapacity >> 1);  // 扩展为原容量的 1.5 倍elementData = Arrays.copyOf(elementData, newCapacity);}
}
2.4 get(int index) 方法

get 方法通过索引直接访问 elementData 数组中的元素。它会先通过 rangeCheck 方法检查索引是否合法,如果不合法会抛出 IndexOutOfBoundsException 异常。

private void rangeCheck(int index) {if (index >= size) {throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);}
}
2.5 remove(int index) 方法

remove 方法会将指定索引的元素移除,并将后续的元素向前移动,确保没有空缺。

public E remove(int index) {rangeCheck(index);E oldValue = (E) elementData[index];int numMoved = size - index - 1;if (numMoved > 0) {System.arraycopy(elementData, index + 1, elementData, index, numMoved);}elementData[--size] = null;  // 清理空闲的元素return oldValue;
}

2.6 ArrayList 性能特点

  • 随机访问ArrayList 提供 O(1) 的时间复杂度来访问任何元素。
  • 插入/删除:在数组的中间插入或删除元素时,性能较差,时间复杂度为 O(n),因为需要移动数组中的元素。

2.7 使用场景

ArrayList 非常适合于需要频繁访问元素而不需要经常进行插入和删除操作的场景,如数据查询、缓存管理等。

3. LinkedList 实现解析

LinkedList 也是 List 接口的一个实现,但它与 ArrayList 不同,底层实现是双向链表。LinkedList 在进行插入和删除操作时具有优势,因为它只需要调整节点的引用,而不需要移动元素。

3.1 LinkedList 类结构

LinkedList 类的核心结构是双向链表,其中每个节点包含一个元素值和指向前后节点的引用。

public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable {transient Node<E> first;transient Node<E> last;private int size;private static class Node<E> {E item;Node<E> next;Node<E> prev;Node(Node<E> prev, E element, Node<E> next) {this.item = element;this.next = next;this.prev = prev;}}public boolean add(E e) {linkLast(e);return true;}private void linkLast(E e) {final Node<E> l = last;final Node<E> newNode = new Node<>(l, e, null);last = newNode;if (l == null)first = newNode;elsel.next = newNode;size++;}public E get(int index) {Node<E> node = node(index);return node.item;}private Node<E> node(int index) {if (index < (size >> 1)) {Node<E> x = first;for (int i = 0; i < index; i++)x = x.next;return x;} else {Node<E> x = last;for (int i = size - 1; i > index; i--)x = x.prev;return x;}}
}

展开

3.2 Node 类

LinkedList 使用内部静态类 Node 来表示链表节点。每个节点包含一个元素以及指向前一个节点和后一个节点的引用,从而实现双向链表结构。

3.3 add(E e) 方法

add 方法会调用 linkLast 方法将元素添加到链表的尾部。linkLast 方法通过调整节点的 prev 和 next 引用来维护链表的连接。

3.4 get(int index) 方法

get 方法通过索引定位到指定的节点。由于链表是线性结构,获取节点时需要遍历链表,时间复杂度为 O(n)。

3.5 LinkedList 性能特点

  • 插入/删除LinkedList 在任意位置插入或删除元素时,性能较好,时间复杂度为 O(1),只需要修改节点的引用。
  • 随机访问:链表访问元素时,时间复杂度为 O(n),比 ArrayList 慢。

3.6 使用场景

LinkedList 适用于需要频繁插入或删除元素的场景,如实现队列、栈等数据结构。

4. 总结

Java 中的 List 接口提供了多种实现方式,常见的有 ArrayList 和 LinkedList。两者各有优缺点:

  • ArrayList:适合随机访问元素,性能较好,但在中间插入和删除时性能较差。
  • LinkedList:适合频繁进行插入和删除操作,尤其是中间位置的插入和删除,但访问元素时性能较差。

理解 List 的实现原理能够帮助我们在实际开发中根据需求选择合适的数据结构,从而提高应用程序的性能和效率

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com