跳转至

Java JDK 8 ArrayList 深度解析

简介

在 Java 编程中,ArrayList 是一个极为常用的动态数组实现类,位于 java.util 包下。它提供了基于索引的快速访问方式,并且能够随着元素的添加和删除自动调整大小。JDK 8 对 ArrayList 进行了一些功能增强和性能优化,本文将深入探讨 JDK 8 中 ArrayList 的基础概念、使用方法、常见实践以及最佳实践。

目录

  1. 基础概念
  2. 使用方法
    • 创建 ArrayList
    • 添加元素
    • 获取元素
    • 修改元素
    • 删除元素
    • 遍历 ArrayList
  3. 常见实践
    • 排序
    • 搜索
    • 转换为数组
    • 从数组转换
  4. 最佳实践
    • 初始化容量
    • 避免频繁的扩容
    • 使用 removeIf 方法删除元素
    • 线程安全问题
  5. 小结

基础概念

ArrayList 是一个基于数组实现的动态列表。它允许动态地添加、删除和访问元素,大小可以根据需要自动调整。与普通数组不同的是,ArrayList 的容量可以在运行时动态变化。

ArrayList 内部维护了一个数组来存储元素,并且有一个字段记录当前实际存储的元素个数。当添加的元素超出当前容量时,ArrayList 会自动扩容,创建一个更大的数组,并将原数组中的元素复制到新数组中。

使用方法

创建 ArrayList

import java.util.ArrayList;
import java.util.List;

public class ArrayListExample {
    public static void main(String[] args) {
        // 创建一个空的 ArrayList
        List<String> list1 = new ArrayList<>();

        // 创建一个指定初始容量的 ArrayList
        List<Integer> list2 = new ArrayList<>(10);

        // 创建一个包含初始元素的 ArrayList
        List<Double> list3 = new ArrayList<>(List.of(1.1, 2.2, 3.3));
    }
}

添加元素

import java.util.ArrayList;
import java.util.List;

public class ArrayListAddExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        // 添加单个元素
        list.add("Apple");
        list.add("Banana");

        // 在指定位置添加元素
        list.add(1, "Cherry");

        System.out.println(list);
    }
}

获取元素

import java.util.ArrayList;
import java.util.List;

public class ArrayListGetExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(List.of("Apple", "Banana", "Cherry"));

        // 获取指定位置的元素
        String element = list.get(1);
        System.out.println(element);
    }
}

修改元素

import java.util.ArrayList;
import java.util.List;

public class ArrayListSetExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(List.of("Apple", "Banana", "Cherry"));

        // 修改指定位置的元素
        list.set(1, "Durian");
        System.out.println(list);
    }
}

删除元素

import java.util.ArrayList;
import java.util.List;

public class ArrayListRemoveExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(List.of("Apple", "Banana", "Cherry"));

        // 删除指定位置的元素
        String removedElement = list.remove(1);
        System.out.println("Removed: " + removedElement);
        System.out.println(list);

        // 删除指定元素
        list.remove("Cherry");
        System.out.println(list);
    }
}

遍历 ArrayList

import java.util.ArrayList;
import java.util.List;

public class ArrayListTraversalExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(List.of("Apple", "Banana", "Cherry"));

        // 传统 for 循环
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        // 增强 for 循环
        for (String element : list) {
            System.out.println(element);
        }

        // Lambda 表达式
        list.forEach(System.out::println);
    }
}

常见实践

排序

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ArrayListSortExample {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>(List.of(3, 1, 4, 1, 5, 9, 2, 6));

        // 自然排序
        Collections.sort(list);
        System.out.println(list);

        // 自定义排序
        Collections.sort(list, Comparator.reverseOrder());
        System.out.println(list);
    }
}

搜索

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ArrayListSearchExample {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>(List.of(1, 2, 3, 4, 5));

        // 二分查找
        int index = Collections.binarySearch(list, 3);
        System.out.println("Index of 3: " + index);
    }
}

转换为数组

import java.util.ArrayList;
import java.util.List;

public class ArrayListToArrayExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(List.of("Apple", "Banana", "Cherry"));

        // 转换为 Object 数组
        Object[] objectArray = list.toArray();

        // 转换为指定类型的数组
        String[] stringArray = list.toArray(new String[0]);
    }
}

从数组转换

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ArrayToListExample {
    public static void main(String[] args) {
        String[] array = {"Apple", "Banana", "Cherry"};

        // 转换为不可变 List
        List<String> immutableList = Arrays.asList(array);

        // 转换为可变 ArrayList
        List<String> mutableList = new ArrayList<>(Arrays.asList(array));
    }
}

最佳实践

初始化容量

在创建 ArrayList 时,如果能够预估元素的大致数量,最好指定初始容量。这样可以避免频繁的扩容操作,提高性能。

List<Integer> list = new ArrayList<>(100);

避免频繁的扩容

频繁的扩容会导致性能下降,因为每次扩容都需要创建新数组并复制元素。尽量在添加元素之前确定合理的容量。

使用 removeIf 方法删除元素

JDK 8 引入的 removeIf 方法可以更方便地删除满足特定条件的元素。

import java.util.ArrayList;
import java.util.List;

public class ArrayListRemoveIfExample {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>(List.of(1, 2, 3, 4, 5));

        // 删除所有偶数
        list.removeIf(num -> num % 2 == 0);
        System.out.println(list);
    }
}

线程安全问题

ArrayList 不是线程安全的。如果在多线程环境中使用,需要进行额外的同步处理。可以使用 Collections.synchronizedList 方法将其转换为线程安全的列表。

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ArrayListThreadSafeExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        List<String> synchronizedList = Collections.synchronizedList(list);
    }
}

小结

本文详细介绍了 Java JDK 8 中 ArrayList 的基础概念、使用方法、常见实践以及最佳实践。通过掌握这些内容,读者能够更加深入地理解 ArrayList 的特性,并在实际编程中高效地使用它。在使用 ArrayList 时,要注意初始化容量、避免频繁扩容、合理使用新特性以及处理多线程安全问题,以提高程序的性能和稳定性。希望本文对您在 Java 编程中使用 ArrayList 有所帮助。