Java基础——List接口及实现类介绍

List 接口是 Java 集合框架中的一个重要部分,它代表一个有序的集合,允许重复的元素。List 接口提供了一些方法,用于插入、删除、访问和遍历列表中的元素。下面是对 List 接口的详细介绍,包括常见的实现及其特点。

List 接口概述

List 接口继承自 Collection 接口,并且提供了一些特有的方法:

public interface List<E> extends Collection<E> {
    // 查询操作
    int size();
    boolean isEmpty();
    boolean contains(Object o);
    Iterator<E> iterator();
    Object[] toArray();
    <T> T[] toArray(T[] a);

    // 修改操作
    boolean add(E e);
    boolean remove(Object o);
    boolean containsAll(Collection<?> c);
    boolean addAll(Collection<? extends E> c);
    boolean addAll(int index, Collection<? extends E> c);
    boolean removeAll(Collection<?> c);
    boolean retainAll(Collection<?> c);
    void clear();

    // 比较和哈希
    boolean equals(Object o);
    int hashCode();

    // 位置访问操作
    E get(int index);
    E set(int index, E element);
    void add(int index, E element);
    E remove(int index);
    int indexOf(Object o);
    int lastIndexOf(Object o);
    ListIterator<E> listIterator();
    ListIterator<E> listIterator(int index);
    List<E> subList(int fromIndex, int toIndex);
}

常见的 List 实现

1. ArrayList
  • 描述: 基于动态数组的实现。
  • 特点:
    • 随机访问性能好,时间复杂度为 O(1)。
    • 插入和删除操作(除尾部外)较慢,时间复杂度为 O(n)。
    • 线程不安全。
  • 适用场景: 需要频繁访问元素而不是频繁插入删除的场景。
List<String> arrayList = new ArrayList<>();
2. LinkedList
  • 描述: 基于双向链表的实现。
  • 特点:
    • 插入和删除操作较快,时间复杂度为 O(1)。
    • 随机访问性能差,时间复杂度为 O(n)。
    • 线程不安全。
  • 适用场景: 需要频繁插入和删除元素的场景。
List<String> linkedList = new LinkedList<>();
3. Vector
  • 描述: 类似于 ArrayList,但线程安全。
  • 特点:
    • 基于动态数组的实现。
    • 大多数方法是同步的,线程安全。
    • 性能相对较差,因为同步开销较大。
  • 适用场景: 需要线程安全的动态数组。
List<String> vector = new Vector<>();
4. CopyOnWriteArrayList
  • 描述: 线程安全的 ArrayList 实现,适用于并发场景。
  • 特点:
    • 所有的可变操作(如 addset 等)都会创建一个新的内部数组。
    • 读操作不会加锁,写操作相对较慢,但读操作非常快。
  • 适用场景: 读多写少的并发场景。
List<String> copyOnWriteArrayList = new CopyOnWriteArrayList<>();

List 接口中的关键方法

  • 添加元素:

    boolean add(E e); // 添加元素到列表的末尾
    void add(int index, E element); // 在指定位置插入元素
    boolean addAll(Collection<? extends E> c); // 添加集合中的所有元素
    boolean addAll(int index, Collection<? extends E> c); // 从指定位置开始添加集合中的所有元素
    
  • 访问元素:

    E get(int index); // 获取指定位置的元素
    E set(int index, E element); // 替换指定位置的元素
    int indexOf(Object o); // 返回第一次出现指定元素的位置
    int lastIndexOf(Object o); // 返回最后一次出现指定元素的位置
    
  • 删除元素:

    E remove(int index); // 删除指定位置的元素
    boolean remove(Object o); // 删除第一次出现的指定元素
    boolean removeAll(Collection<?> c); // 删除列表中包含在指定集合中的所有元素
    void clear(); // 清空列表中的所有元素
    
  • 遍历元素:

    Iterator<E> iterator(); // 获取列表的迭代器
    ListIterator<E> listIterator(); // 获取列表的列表迭代器
    ListIterator<E> listIterator(int index); // 从指定位置开始获取列表的列表迭代器
    
  • 其他方法:

    int size(); // 返回列表的元素个数
    boolean isEmpty(); // 检查列表是否为空
    boolean contains(Object o); // 检查列表是否包含指定元素
    Object[] toArray(); // 返回包含列表所有元素的数组
    <T> T[] toArray(T[] a); // 返回包含列表所有元素的数组,数组类型由参数确定
    List<E> subList(int fromIndex, int toIndex); // 返回从fromIndex到toIndex的子列表
    

安全性考虑

在多线程环境中使用 List 时,需要特别注意线程安全问题。以下是一些常用的确保线程安全的方法:

  • 使用线程安全的 List 实现:

    • VectorCopyOnWriteArrayList 是线程安全的,可以直接在多线程环境中使用。
  • 使用 Collections.synchronizedList:

    • 将非线程安全的 List 转换为线程安全的 List
    List<String> list = new ArrayList<>();
    List<String> synchronizedList = Collections.synchronizedList(list);
    
  • 手动同步:

    • 手动同步访问 List 的代码块。
    List<String> list = new ArrayList<>();
    synchronized (list) {
        list.add("example");
    }
    

通过理解和正确使用 List 接口及其实现,可以有效地管理和操作有序的集合数据,同时在需要的场景下确保线程安全。

  • 15
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值