List接口详解

本文详细介绍了Java中List接口及其常用实现类ArrayList和LinkedList,包括它们的特点、常用方法以及使用场景。ArrayList适合随机访问,而LinkedList在插入和删除操作上更高效。还探讨了LinkedList作为Queue接口的实现,以及提供了示例代码展示List接口的各种操作。
摘要由CSDN通过智能技术生成

List接口详解

List接口的定义

List接口是Java集合框架中的一个接口,继承自Collection接口。List接口用于表示一个有序、可重复的集合,可以通过索引(位置)来访问和修改其中的元素。List接口的常用实现类包括ArrayList、LinkedList和Vector等。

List接口定义的方法
  • 添加元素:add(E e)、add(int index, E element)、addAll(Collection<? extends E> c)、addAll(int index, Collection<? extends E> c)等方法;
  • 删除元素:remove(Object o)、remove(int index)、removeAll(Collection<?> c)等方法;
  • 获取元素:get(int index)、subList(int fromIndex, int toIndex)等方法;
  • 修改元素:set(int index, E element)等方法;
  • 获取列表大小:size()方法;
  • 判断列表是否为空:isEmpty()方法;
  • 判断是否包含某个元素:contains(Object o)、containsAll(Collection<?> c)等方法;
  • 清空列表:clear()方法;
  • 获取列表中某个元素的索引位置:indexOf(Object o)、lastIndexOf(Object o)等方法;
  • 迭代器:listIterator()、listIterator(int index)等方法。

List接口还定义了一些特殊的操作,比如获取子列表、反转列表等,以及用于排序的sort方法。

List接口的常用子类

ArrayList

实现了可调整大小的数组,支持快速随机访问,插入和删除操作的效率较低;

LinkedList

实现了基于双向链表的列表,支持快速插入和删除操作,但不支持随机访问;

Vector

类似于ArrayList,但是是线程安全的,因此效率较低,已经不建议使用,可以使用CopyOnWriteArrayList代替;

CopyOnWriteArrayList

是一个线程安全的ArrayList,每次修改时都会复制一份新的数组,因此不适合大量的修改操作。

LinkedList 子类与 Queue 接口

LinkedList是Java中List接口的一个实现类,同时也实现了Deque和Queue接口。Queue是Java中一个单独的接口,继承自Collection接口,代表了一组队列操作,比如添加元素到队列尾部、从队列头部取出元素等。

LinkedList作为一个List集合实现,可以进行List中的各种操作,同时作为一个Queue实现,也可以进行队列操作。可以使用LinkedList实现先进先出(FIFO)的队列,也可以实现后进先出(LIFO)的栈。

深入探讨ArrayList和LinkedList的使用场景和优劣

ArrayList和LinkedList是Java中常用的List集合实现类,它们都实现了List接口,但是底层实现机制不同,因此在不同的场景下,选择使用哪个集合会有不同的效果。

ArrayList是基于数组实现的动态数组,它的优点是支持快速随机访问,因为元素在内存中是连续存储的,因此可以通过索引直接访问到元素。同时,由于ArrayList底层采用的是数组实现,因此可以提供高效的随机访问、添加、删除等操作。缺点是在进行添加或删除操作时需要进行大量的数组复制操作,如果数据量比较大的话,这些操作会非常耗时。另外,由于ArrayList内部使用数组实现,因此它的大小是固定的,当元素数量超出数组大小时,需要进行扩容操作,也会导致性能问题。

LinkedList是基于链表实现的列表,它的优点是支持快速的插入和删除操作,因为只需要改变节点的指向即可,不需要进行数组复制操作。另外,LinkedList在进行插入和删除操作时不需要移动其他元素的位置,因此它的效率不受集合大小的影响。缺点是访问元素时需要遍历链表,因此效率较低,不支持随机访问。

从上述特点来看,当需要进行随机访问时,使用ArrayList会更加高效,因为它可以直接通过索引访问元素。而当需要进行插入和删除操作时,使用LinkedList会更加高效,因为它不需要进行数组复制操作。

另外,需要注意的是,在多线程环境下,ArrayList和LinkedList都不是线程安全的,因此需要进行同步处理。如果需要在多线程环境下使用List集合,可以使用线程安全的CopyOnWriteArrayList,或者使用Collections.synchronizedList方法包装List集合实现同步操作。

总之,对于需要进行随机访问操作的场景,选择ArrayList会更加高效,而对于需要进行插入和删除操作的场景,选择LinkedList会更加高效。同时,需要考虑集合的大小和多线程安全等因素,在选择使用哪个集合时,需要进行综合考虑。

示例代码
示例1:向集合中增加元素、删除元素、输出全部元素、将集合变为对象数组的操作
import java.util.ArrayList;
import java.util.List;

public class CollectionDemo {

    public static void main(String[] args) {
        
        // 创建一个 List 集合
        List<String> list = new ArrayList<>();

        // 向集合中添加元素的方法1:add()
        list.add("apple");
        list.add("banana");
        list.add("cherry");
        
        // 向集合中添加元素的方法2:addAll()
        List<String> moreFruits = new ArrayList<>();
        moreFruits.add("durian");
        moreFruits.add("elderberry");
        moreFruits.add("fig");
        list.addAll(moreFruits);

        // 输出集合中所有元素
        System.out.println("输出集合中所有元素:");
        for (String fruit : list) {
            System.out.println(fruit);
        }
        
        // 将集合变为对象数组的方法1:toArray()
        Object[] objArr = list.toArray();
        System.out.println("\n将集合变为对象数组的方法1:");
        for (int i = 0; i < objArr.length; i++) {
            System.out.print(objArr[i] + " ");
        }

        // 将集合变为对象数组的方法2:toArray(T[] a)
        String[] strArr = list.toArray(new String[0]); // 注意:传入的参数类型要与目标数组元素类型一致
        System.out.println("\n\n将集合变为对象数组的方法2:");
        for (int i = 0; i < strArr.length; i++) {
            System.out.print(strArr[i] + " ");
        }
        
        // 从集合中删除元素的方法1:remove()
        list.remove("banana");
        
        // 从集合中删除元素的方法2:removeAll()
        List<String> toRemove = new ArrayList<>();
        toRemove.add("cherry");
        toRemove.add("fig");
        list.removeAll(toRemove);
        
        // 输出删除元素后集合中所有元素
        System.out.println("\n\n删除元素后集合中所有元素:");
        for (String fruit : list) {
            System.out.println(fruit);
        }
    }
}
示例2:对List进行截取、查找元素位置、判断元素是否存在、集合是否为空等操作
import java.util.ArrayList;
import java.util.List;

public class ListExample {
    public static void main(String[] args) {
        // 创建一个List集合,并添加一些元素
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("Python");
        list.add("C++");
        list.add("JavaScript");
        list.add("PHP");
        System.out.println("集合中的元素为:" + list);

        // 截取集合中的元素
        List<String> subList = list.subList(1, 4);
        System.out.println("截取后的集合中的元素为:" + subList);

        // 查找元素位置
        int index1 = list.indexOf("C++");
        int index2 = list.indexOf("Ruby");
        System.out.println("元素C++的位置为:" + index1);
        System.out.println("元素Ruby的位置为:" + index2);

        // 判断元素是否存在
        boolean contains1 = list.contains("Python");
        boolean contains2 = list.contains("Perl");
        System.out.println("集合中是否包含元素Python:" + contains1);
        System.out.println("集合中是否包含元素Perl:" + contains2);

        // 判断集合是否为空
        boolean isEmpty1 = list.isEmpty();
        list.clear();
        boolean isEmpty2 = list.isEmpty();
        System.out.println("集合是否为空:" + isEmpty1);
        System.out.println("清空集合后,集合是否为空:" + isEmpty2);
    }
}
示例3:LinkedList的一些常用方法
import java.util.LinkedList;
import java.util.Queue;

public class LinkedListQueueExample {
    public static void main(String[] args) {
        // 创建一个 LinkedList 实例
        LinkedList<String> linkedList = new LinkedList<>();

        // 将元素添加到队列尾部
        linkedList.add("A");
        linkedList.add("B");
        linkedList.add("C");

        // 使用队列方法取出队列头部元素并删除该元素
        System.out.println(linkedList.poll()); // 输出 A

        // 使用队列方法取出队列头部元素但不删除该元素
        System.out.println(linkedList.peek()); // 输出 B

        // 使用队列方法获取队列大小
        System.out.println(linkedList.size()); // 输出 2

        // 将元素添加到队列尾部
        linkedList.offer("D");

        // 遍历队列并输出每个元素
        for (String s : linkedList) {
            System.out.println(s);
        }
    }
}

LinkedList实现了Queue接口中的offer()poll()peek()方法,用于在队列中添加元素、取出队列头部元素并删除该元素,以及取出队列头部元素但不删除该元素。此外,LinkedList还实现了List接口中的add()方法,用于在队列尾部添加元素。同时,我们还可以使用size()方法获取队列大小,在这个例子中输出了2,因为我们已经取出了队列中的第一个元素。

示例4:增加数据、找到链表头以及以FIFO方式取出内容
import java.util.LinkedList;

public class LinkedListDemo {
    public static void main(String[] args) {
        // 创建一个 LinkedList
        LinkedList<String> linkedList = new LinkedList<>();

        // 添加元素
        linkedList.add("Java");
        linkedList.add("Python");
        linkedList.add("C++");
        linkedList.add("JavaScript");

        // 找到链表头
        String head = linkedList.getFirst();
        System.out.println("链表头为:" + head);

        // 以FIFO方式取出内容
        while (!linkedList.isEmpty()) {
            String element = linkedList.poll(); // 弹出链表头元素
            System.out.println("取出元素:" + element);
        }
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

参果

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值