深入理解Java List:掌握数据结构中的利器

《Java零基础教学》是一套深入浅出的 Java 编程入门教程。全套教程从Java基础语法开始,适合初学者快速入门,同时也从实例的角度进行了深入浅出的讲解,让初学者能够更好地理解Java编程思想和应用。

本教程内容包括数据类型与运算、流程控制、数组、函数、面向对象基础、字符串、集合、异常处理、IO 流及多线程等 Java 编程基础知识,并提供丰富的实例和练习,帮助读者巩固所学知识。本教程不仅适合初学者学习,也适合已经掌握一定 Java 基础的读者进行查漏补缺。

深入理解Java List

前言

在Java编程中,List是我们经常使用的数据结构之一。它是一个有序的集合,可以存储重复的元素。List提供了很多有用的方法来操作集合中的元素,包括添加,删除,获取等操作。在本文中,我们将深入理解Java中List的实现原理及其基本操作。

摘要

本文主要针对Java中List的数据结构进行深入探讨,包括List的基本原理,常见的List实现类,以及List的常用操作方法等。通过本文的学习,你将会更加深入地理解List,为以后的编程工作打下坚实的基础。

内容

List的基本原理

在Java编程中,List是一个接口,它继承了Collection接口,定义了一些有序集合的方法。List可以存放对象类型的元素,并且可以存储重复的元素。在Java中,List的实现类有很多种,包括ArrayList,LinkedList,Vector等。

常见的List实现类

ArrayList

ArrayList是一个基于数组实现的List,它可以动态地增加和缩小数组的大小,因此可以容纳任意数量的元素。由于它是数组实现的,因此可以随机访问元素,因此可以实现高效的查找操作。但是,由于它是基于数组实现的,因此在插入和删除操作时,需要将后面的元素往后移或往前移,因此效率相对较低。

LinkedList

LinkedList是一个基于链表实现的List,它每个元素都包含了一个指向前一个元素和后一个元素的指针,因此可以方便地在任意位置进行插入和删除操作。但是,由于它是基于链表实现的,因此无法随机访问元素,因此在查找操作时效率相对较低。

Vector

Vector是一个线程安全的List实现类,它类似于ArrayList,但是所有的操作都是同步的。由于是线程安全的,因此在多线程环境下使用比较安全。

List的常用操作方法

增加元素

在List中增加元素有多种方法,最常见的是add()方法,可以将元素添加到List的末尾,也可以通过指定索引的方式将元素插入到List中。如下所示:

java 复制代码
List<String> list = new ArrayList<>();
list.add("apple"); // 在List末尾添加元素
list.add(0, "banana"); // 在List的第一个位置插入元素

删除元素

在List中删除元素也有多种方法,最常见的是remove()方法,可以按照元素或者索引来删除元素。如下所示:

java 复制代码
List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("cherry");
list.remove("banana"); // 删除指定元素
list.remove(0); // 删除第一个元素

获取元素

在List中获取元素也有多种方法,最常见的是get()方法,可以按照索引来获取元素。如下所示:

java 复制代码
List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("cherry");
String fruit = list.get(1); // 获取第二个元素

更新元素

在List中更新元素也有多种方法,最常见的是set()方法,可以按照索引来更新元素。如下所示:

java 复制代码
List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("cherry");
list.set(1, "pear"); // 将第二个元素更新为pear

遍历List

遍历List的方法有多种,最常见的是使用for循环或者foreach循环。如下所示:

java 复制代码
List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("cherry");
for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}
for (String fruit : list) {
    System.out.println(fruit);
}

代码方法介绍

add()方法

add()方法是向List中增加元素的方法,它有两个重载方法,一个是将元素添加到List的末尾,一个是通过指定索引的方式将元素插入到List中。如下所示:

java 复制代码
public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

public void add(int index, E element) {
    rangeCheckForAdd(index);

    ensureCapacityInternal(size + 1);  // Increments modCount!!
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index);
    elementData[index] = element;
    size++;
}

remove()方法

remove()方法是删除List中元素的方法,它有两个重载方法,一个是按照元素删除,一个是按照索引删除。如下所示:

java 复制代码
public boolean remove(Object o) {
    if (o == null) {
        for (int index = 0; index < size; index++)
            if (elementData[index] == null) {
                fastRemove(index);
                return true;
            }
    } else {
        for (int index = 0; index < size; index++)
            if (o.equals(elementData[index])) {
                fastRemove(index);
                return true;
            }
    }
    return false;
}

public E remove(int index) {
    rangeCheck(index);

    modCount++;
    E oldValue = elementData(index);

    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                numMoved);
    elementData[--size] = null; // clear to let GC do its work

    return oldValue;
}

get()方法

get()方法是获取List中元素的方法,它只有一个重载方法,就是按照索引获取元素。如下所示:

java 复制代码
public E get(int index) {
    rangeCheck(index);

    return elementData(index);
}

set()方法

set()方法是更新List中元素的方法,它只有一个重载方法,就是按照索引更新元素。如下所示:

java 复制代码
public E set(int index, E element) {
    rangeCheck(index);

    E oldValue = elementData(index);
    elementData[index] = element;
    return oldValue;
}

测试用例

以下是一些测试用例:

测试增加元素

java 复制代码
    //新增元素
    @Test
    public void testAdd() {
        List<String> fruitList = new ArrayList<>();
        fruitList.add("apple");
        fruitList.add("banana");
        fruitList.add("cherry");
        System.out.println(fruitList);
        assertEquals(3, fruitList.size());
    }

测试用例执行截图:

测试删除元素

java 复制代码
    //删除元素
    @Test
    public void testRemove() {
        List<String> fruitList = new ArrayList<>();
        fruitList.add("apple");
        fruitList.add("banana");
        fruitList.add("cherry");
        System.out.println("删除前:"+fruitList);
        fruitList.remove("banana");
        System.out.println("删除后:"+fruitList);
        assertEquals(2, fruitList.size());
    }

测试用例执行截图:

测试获取元素

java 复制代码
    //查询元素
    @Test
    public void testGet() {
        List<String> fruitList = new ArrayList<>();
        fruitList.add("apple");
        fruitList.add("banana");
        fruitList.add("cherry");
        String fruit = fruitList.get(1);
        System.out.println("fruitList.get(1) = " +fruit);
        assertEquals("banana", fruit);
    }

测试用例执行截图:

测试获取元素

java 复制代码
    //更新元素
    @Test
    public void testSet() {
        List<String> fruitList = new ArrayList<>();
        fruitList.add("apple");
        fruitList.add("banana");
        fruitList.add("cherry");
        System.out.println("更新前:"+fruitList);
        fruitList.set(1, "pear");
        System.out.println("更新后:"+fruitList);
        assertEquals("pear", fruitList.get(1));
    }

测试用例执行截图:

全文小结

Java List 接口的实现类包括 ArrayList、LinkedList 和 Vector,它们都提供了类似数组的随机访问和迭代器的顺序访问两种方式访问集合元素。不同的实现类在性能、并发性、安全性等方面有所不同,因此要根据具体应用场景选择合适的实现类。

ArrayList 是最常用的 List 实现类之一,它底层采用数组实现,因此可以快速随机访问元素,但插入、删除元素较慢。LinkedList 底层采用链表实现,因此插入、删除元素速度较快,但随机访问效率较低。Vector 与 ArrayList 类似,但是支持线程安全,不过在多线程环境下性能较低。

在使用 List 进行开发时,需要注意以下几点:

  1. 插入和删除操作会影响到集合中元素的位置,因此需要注意元素下标的变化;
  2. 使用迭代器进行顺序访问时,不能改变集合的大小,否则可能会引发 ConcurrentModificationException 异常;
  3. 在多线程环境下,需要注意并发修改的问题,可以使用线程安全的实现类或加锁的方式解决。

总之,掌握 Java List 的使用方法和实现原理对于 Java 开发者来说是非常必要的,会在数据结构的选择和代码效率方面给予帮助。Java List 是 Java 集合框架中最常用的数据结构之一,它是一种线性数据结构,可以按照一定顺序存储一系列元素。

最后

大家如果觉得看了本文有帮助的话,麻烦给个三连(点赞、分享、转发)支持一下哈。

相关推荐
m0_571957582 小时前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
魔道不误砍柴功4 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2344 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨4 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
Chrikk5 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*5 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue5 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man5 小时前
【go从零单排】go语言中的指针
开发语言·后端·golang
测开小菜鸟5 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity6 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq