跳转至

Java JDK 8 List 深度解析

简介

在 Java 编程中,List 是一个极为重要的接口,它提供了一种有序且可重复的数据存储方式。JDK 8 为 List 接口带来了许多强大的新特性和改进,使得对列表的操作更加简洁、高效和灵活。本文将深入探讨 Java JDK 8 中 List 的基础概念、使用方法、常见实践以及最佳实践,帮助读者更好地掌握和运用这一强大的数据结构。

目录

  1. 基础概念
    • List 接口概述
    • List 与其他集合接口的区别
  2. 使用方法
    • 创建 List 对象
    • 基本操作(添加、删除、查询、修改)
    • 遍历 List
  3. 常见实践
    • 排序
    • 过滤
    • 映射
    • 查找
  4. 最佳实践
    • 选择合适的 List 实现类
    • 避免不必要的装箱和拆箱
    • 优化性能
  5. 小结

基础概念

List 接口概述

List 接口是 Java 集合框架的一部分,它继承自 Collection 接口。List 接口的主要特点是它存储的元素是有序的,并且可以包含重复的元素。这意味着可以通过索引来访问 List 中的元素,就像数组一样。

List 与其他集合接口的区别

Set 接口不同,Set 中的元素是无序且唯一的,而 List 允许元素重复并且有顺序。Map 接口则是用于存储键值对,与 List 的数据结构有本质区别。

使用方法

创建 List 对象

在 JDK 8 中,可以使用多种方式创建 List 对象。 - 使用 ArrayList 实现类

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

public class ListCreation {
    public static void main(String[] args) {
        List<String> list1 = new ArrayList<>();
        List<Integer> list2 = new ArrayList<>(10); // 初始化容量为10
    }
}
  • 使用 Arrays.asList() 方法
import java.util.Arrays;
import java.util.List;

public class ListCreation {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("apple", "banana", "cherry");
    }
}
  • 使用 Collections.emptyList() 方法创建不可变空列表
import java.util.Collections;
import java.util.List;

public class ListCreation {
    public static void main(String[] args) {
        List<String> emptyList = Collections.emptyList();
    }
}

基本操作

  • 添加元素
import java.util.ArrayList;
import java.util.List;

public class ListOperations {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("apple");
        list.add(0, "banana"); // 在指定位置插入元素
    }
}
  • 删除元素
import java.util.ArrayList;
import java.util.List;

public class ListOperations {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(Arrays.asList("apple", "banana", "cherry"));
        list.remove("banana");
        list.remove(1); // 根据索引删除元素
    }
}
  • 查询元素
import java.util.ArrayList;
import java.util.List;

public class ListOperations {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(Arrays.asList("apple", "banana", "cherry"));
        boolean contains = list.contains("banana");
        int index = list.indexOf("cherry");
    }
}
  • 修改元素
import java.util.ArrayList;
import java.util.List;

public class ListOperations {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(Arrays.asList("apple", "banana", "cherry"));
        list.set(1, "dragonfruit");
    }
}

遍历 List

  • 传统 for 循环
import java.util.ArrayList;
import java.util.List;

public class ListTraversal {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(Arrays.asList("apple", "banana", "cherry"));
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }
}
  • 增强 for 循环
import java.util.ArrayList;
import java.util.List;

public class ListTraversal {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(Arrays.asList("apple", "banana", "cherry"));
        for (String fruit : list) {
            System.out.println(fruit);
        }
    }
}
  • 使用 Iterator
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ListTraversal {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(Arrays.asList("apple", "banana", "cherry"));
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}
  • 使用 Lambda 表达式(JDK 8 新特性)
import java.util.ArrayList;
import java.util.List;

public class ListTraversal {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(Arrays.asList("apple", "banana", "cherry"));
        list.forEach(System.out::println);
    }
}

常见实践

排序

  • 自然排序
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ListSorting {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>(Arrays.asList(3, 1, 4, 1, 5, 9));
        Collections.sort(list);
        System.out.println(list);
    }
}
  • 自定义排序
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

public class ListSorting {
    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        list.add(new Person("Alice", 25));
        list.add(new Person("Bob", 20));
        list.add(new Person("Charlie", 30));

        Collections.sort(list, Comparator.comparingInt(Person::getAge));
        list.forEach(p -> System.out.println(p.getName() + " : " + p.getAge()));
    }
}

过滤

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class ListFiltering {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6));
        List<Integer> evenList = list.stream()
             .filter(num -> num % 2 == 0)
             .collect(Collectors.toList());
        System.out.println(evenList);
    }
}

映射

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class ListMapping {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(Arrays.asList("apple", "banana", "cherry"));
        List<Integer> lengthList = list.stream()
             .map(String::length)
             .collect(Collectors.toList());
        System.out.println(lengthList);
    }
}

查找

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

public class ListSearching {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
        Optional<Integer> firstEven = list.stream()
             .filter(num -> num % 2 == 0)
             .findFirst();
        firstEven.ifPresent(System.out::println);
    }
}

最佳实践

选择合适的 List 实现类

  • ArrayList:适合随机访问,内部实现基于数组,添加和删除操作在列表末尾效率高,在中间或开头效率低。
  • LinkedList:适合频繁的插入和删除操作,内部实现基于双向链表,随机访问效率低。

避免不必要的装箱和拆箱

在使用泛型 List 时,尽量使用基本数据类型的包装类,避免频繁的装箱和拆箱操作,以提高性能。

优化性能

  • 预分配足够的容量:如果知道 List 的大致大小,在创建 ArrayList 时可以预分配容量,减少动态扩容的次数。
  • 使用并行流:对于大数据集的操作,可以考虑使用并行流来提高处理速度,但要注意并行流可能带来的线程安全问题。

小结

本文详细介绍了 Java JDK 8 中 List 的基础概念、使用方法、常见实践以及最佳实践。通过学习这些内容,读者能够更加深入地理解 List 接口及其各种操作,并且能够在实际编程中选择合适的方法和实现类,以提高代码的效率和质量。希望本文能对读者在使用 Java List 时有所帮助。