集合框架

数据

在Java中,数组是一种用来存储相同类型数据的数据结构。数组的大小在创建时就确定,并且不能动态改变。

声明和初始化数组

// 声明一个整型数组
int[] intArray;

// 初始化一个包含5个元素的整型数组
intArray = new int[5];

// 声明并初始化一个整型数组
int[] anotherArray = {1, 2, 3, 4, 5};

访问数组元素

int[] intArray = {10, 20, 30, 40, 50};

// 访问数组元素
int element = intArray[2]; // 获取第3个元素,值为30

遍历数组

int[] intArray = {10, 20, 30, 40, 50};

// 使用for循环遍历数组
for (int i = 0; i < intArray.length; i++) {
    System.out.println(intArray[i]);
}

// 使用增强for循环遍历数组
for (int num : intArray) {
    System.out.println(num);
}

数组实现对象的增删改查

增加对象

要向数组中添加新的对象,需要先创建一个新的数组,将原数组中的元素复制到新数组中,并在新数组末尾添加新的对象。

// 增加对象示例
// 假设有一个存储学生对象的数组
Student[] studentArray = new Student[3]; // 原数组大小为3

// 创建一个新的学生对象
Student newStudent = new Student("Alice", 20);

// 创建一个新的数组,大小比原数组大1
Student[] newStudentArray = new Student[studentArray.length + 1];

// 将原数组中的元素复制到新数组中
for (int i = 0; i < studentArray.length; i++) {
    newStudentArray[i] = studentArray[i];
}

// 在新数组末尾添加新的学生对象
newStudentArray[studentArray.length] = newStudent;

// 将新数组赋值给原数组
studentArray = newStudentArray;

删除对象

要从数组中删除对象,需要找到要删除的对象在数组中的位置,然后创建一个新的数组,将原数组中除了要删除对象的元素复制到新数组中。

// 删除对象示例
// 假设有一个存储学生对象的数组
Student[] studentArray = {new Student("Alice", 20), new Student("Bob", 21), new Student("Charlie", 22)};

// 假设要删除Bob这个学生对象
String studentNameToDelete = "Bob";

// 找到要删除对象的位置
int indexToDelete = -1;
for (int i = 0; i < studentArray.length; i++) {
    if (studentArray[i].getName().equals(studentNameToDelete)) {
        indexToDelete = i;
        break;
    }
}

// 创建一个新的数组,大小比原数组小1
Student[] newStudentArray = new Student[studentArray.length - 1];

// 将原数组中除了要删除对象的元素复制到新数组中
int newIndex = 0;
for (int i = 0; i < studentArray.length; i++) {
    if (i != indexToDelete) {
        newStudentArray[newIndex] = studentArray[i];
        newIndex++;
    }
}

// 将新数组赋值给原数组
studentArray = newStudentArray;

修改对象

要修改数组中的对象,只需直接访问对象所在的位置,并进行修改。

// 修改对象示例
// 假设有一个存储学生对象的数组
Student[] studentArray = {new Student("Alice", 20), new Student("Bob", 21), new Student("Charlie", 22)};

// 假设要修改Bob这个学生对象的年龄为25
String studentNameToModify = "Bob";
int newAge = 25;

// 找到要修改对象的位置
for (int i = 0; i < studentArray.length; i++) {
    if (studentArray[i].getName().equals(studentNameToModify)) {
        studentArray[i].setAge(newAge);
        break;
    }
}

查找对象

要在数组中查找对象,需要遍历数组,逐个比较对象的属性与目标值。

// 查找对象示例
// 假设有一个存储学生对象的数组
Student[] studentArray = {new Student("Alice", 20), new Student("Bob", 21), new Student("Charlie", 22)};

// 假设要查找年龄为21的学生对象
int targetAge = 21;

// 遍历数组,逐个比较年龄属性
for (Student student : studentArray) {
    if (student.getAge() == targetAge) {
        System.out.println("找到年龄为21的学生:" + student.getName());
        break;
    }
}

注意事项

  • 数组的下标从0开始。

  • 数组一旦创建后,大小就固定了,不能动态改变。

  • 数组中的元素必须是相同类型。

  • 数组无法求出真实有效数据的个数

  • 用数组实现对象的增删改查比较麻烦

java集合框架接口和类 关系图

Java集合框架接口和类关系图

                    +---------------------+
                    |      Collection     |
                    +----------+----------+
                               ^
                               |
                    +----------+----------+
                    |                     |
                    |                     |
          +---------+---------+   +-------+-------+
          |                   |   |               |
          |                   |   |               |
+---------+---------+   +-----+-----+   +---------+---------+
|      List         |   |     Set     |   |       Queue      |
+-------------------+   +-------------+   +-------------------+
|                     |   |             |   |                   |
|                     |   |             |   |                   |
|  +----------------+ |   |             |   |                   |
|  |                | |   |             |   |                   |
|  |                | |   |             |   |                   |
|  |  ArrayList     | |   |   HashSet   |   |      LinkedList   |
|  |  LinkedList    | |   |   TreeSet   |   |      PriorityQueue |
|  |  Vector        | |   |             |   |                   |
|  |  Stack         | |   |             |   |                   |
|  +----------------+ |   |             |   |                   |
|                     |   |             |   |                   |
+---------------------+   +-------------+   +-------------------+
                    Map
          +---------+---------+
          |                   |
          |                   |
+---------+---------+   +-----+-----+
|        Map        |   |   SortedMap  |
+-------------------+   +-------------+
|                     |   |             |
|                     |   |             |
|  +----------------+ |   |             |
|  |                | |   |             |
|  |                | |   |             |
|  |   HashMap      | |   |   TreeMap   |
|  |   LinkedHashMap| |   |             |
|  |   Hashtable    | |   |             |
|  |   ConcurrentHashMap |   |             |
|  +----------------+ |   |             |
|                     |   |             |
+---------------------+   +-------------+

Collection

LinkedList

LinkedList 是 Java 集合框架中 List 接口的实现类,它基于双向链表实现。以下是关于 LinkedList 的特点:

  • 可以高效地在列表的开头和结尾进行元素的插入和删除操作。

  • 支持快速的随机访问,但效率比 ArrayList 低。

  • 适用于需要频繁插入和删除操作的场景。

ArrayList

ArrayList 也是 Java 集合框架中 List 接口的实现类,它基于动态数组实现。以下是关于 ArrayList 的特点:

  • 支持快速的随机访问,因为它基于数组实现。

  • 在末尾进行元素的插入和删除操作效率高,但在中间插入和删除操作效率较低。

  • 适用于需要频繁随机访问元素的场景。

HashSet

HashSet 是 Java 集合框架中 Set 接口的实现类,它基于哈希表实现。以下是关于 HashSet 的特点:

  • 不允许存储重复元素。

  • 不保证集合中元素的顺序,即不保证元素的插入顺序和遍历顺序一致。

  • 适用于需要快速查找元素且不关心元素顺序的场景。

TreeSet

TreeSet 是 Java 集合框架中 Set 接口的实现类,它基于红黑树实现。以下是关于 TreeSet 的特点:

  • TreeSet 是有序的,它会根据元素的自然顺序或者自定义比较器来维护元素的顺序。

  • 不允许存储重复元素。

  • 适用于需要有序存储元素的场景。

两个 Queue

LinkedList 实现的 Queue

LinkedList 也可以用来实现 Queue 接口,作为队列使用。以下是关于 LinkedList 实现的 Queue 的特点:

  • 支持队列的基本操作,如入队(offer)、出队(poll)、获取队首元素(peek)等。

  • 可以实现先进先出(FIFO)的队列。

PriorityQueue

PriorityQueue 是 Java 集合框架中 Queue 接口的实现类,它是一个优先级队列。以下是关于 PriorityQueue 的特点:

  • PriorityQueue 是基于堆实现的,可以按照元素的优先级顺序进行出队操作。

  • 元素根据其自然顺序或者自定义比较器来确定优先级。

  • 适用于需要按照优先级顺序处理元素的场景。

迭代器

迭代器(Iterator)是集合框架中的一个接口,用于遍历集合中的元素。通过迭代器,可以依次访问集合中的每个元素,而不需要了解集合的内部结构。

迭代器接口定义了以下常用方法:

  • boolean hasNext():判断集合中是否还有下一个元素。

  • E next():返回集合中的下一个元素,并将迭代器的指针向后移动一位。

  • void remove():从集合中删除迭代器返回的最后一个元素(可选操作)。

以下是一个使用迭代器遍历集合的示例代码:

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

public class IteratorExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Apple");
        list.add("Banana");
        list.add("Orange");

        // 使用迭代器遍历集合
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String element = iterator.next();
            System.out.println(element);
        }
    }
}

在上面的示例中,我们创建了一个ArrayList集合,并向其中添加了三个元素。然后,我们通过调用iterator()方法获取集合的迭代器对象。接下来,我们使用while循环和hasNext()方法判断集合中是否还有下一个元素,如果有,则使用next()方法获取下一个元素并打印出来。

需要注意的是,在使用迭代器遍历集合时,如果在遍历过程中修改了集合的结构(如添加或删除元素),会抛出ConcurrentModificationException异常。如果需要在遍历过程中修改集合,可以使用迭代器的remove()方法来删除元素。

增强for循环

增强 for 循环

增强 for 循环(也称为“for-each”循环)是 Java 中用于遍历集合和数组的一种简化语法。它使得遍历集合或数组的代码更加简洁和易读。增强 for 循环的语法如下:

for (元素类型 元素 : 集合或数组) {
    // 对元素的操作
}

特点

  • 简洁性:增强 for 循环不需要使用索引或迭代器,代码更加简洁。

  • 可读性:增强 for 循环的语法更接近自然语言,易于理解。

  • 安全性:在遍历过程中不容易出现越界或其他常见错误。

示例代码

以下是一个使用增强 for 循环遍历 ArrayList 的示例:

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

public class EnhancedForLoopExample {
    public static void main(String[] args) {
        // 创建一个 ArrayList 并添加元素
        List<String> fruits = new ArrayList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Orange");

        // 使用增强 for 循环遍历集合
        for (String fruit : fruits) {
            System.out.println(fruit);
        }
    }
}

输出结果

Apple
Banana
Orange

遍历数组的示例

增强 for 循环同样适用于数组,以下是一个遍历整型数组的示例:

public class EnhancedForLoopArrayExample {
    public static void main(String[] args) {
        // 声明并初始化一个整型数组
        int[] numbers = {1, 2, 3, 4, 5};

        // 使用增强 for 循环遍历数组
        for (int number : numbers) {
            System.out.println(number);
        }
    }
}

输出结果

1
2
3
4
5

注意事项

  • 增强 for 循环只能用于读取元素,不能用于修改集合或数组的结构(如添加或删除元素)。

  • 如果需要在遍历过程中修改集合的内容,建议使用传统的 for 循环或迭代器。

增强 for 循环是 Java 中非常实用的特性,能够提高代码的可读性和简洁性,适合用于大多数遍历场景。

泛型

泛型是 Java 中的一种特性,它允许在类、接口和方法中定义类型参数,从而使代码更加灵活和可重用。通过使用泛型,可以在编译时检查类型安全,避免在运行时出现类型转换异常。

泛型的优点

  1. 类型安全:使用泛型可以在编译时检查类型,减少运行时错误。

  2. 代码重用:可以编写通用的算法和数据结构,适用于多种类型。

  3. 消除强制类型转换:使用泛型后,不需要在使用集合时进行类型转换,代码更加简洁。

泛型类

泛型类是指在类定义时使用类型参数的类。以下是一个简单的泛型类示例:

// 定义一个泛型类 Box
public class Box<T> {
    private T item;

    public void setItem(T item) {
        this.item = item;
    }

    public T getItem() {
        return item;
    }
}

// 使用泛型类
public class GenericClassExample {
    public static void main(String[] args) {
        // 创建一个 Box 对象,存储 String 类型
        Box<String> stringBox = new Box<>();
        stringBox.setItem("Hello, Generics!");
        System.out.println(stringBox.getItem());

        // 创建一个 Box 对象,存储 Integer 类型
        Box<Integer> integerBox = new Box<>();
        integerBox.setItem(123);
        System.out.println(integerBox.getItem());
    }
}

输出结果

Hello, Generics!
123

泛型方法

泛型方法是指在方法定义时使用类型参数的方法。以下是一个泛型方法的示例:

// 定义一个泛型方法
public class GenericMethodExample {
    // 泛型方法,接受一个数组并打印数组中的元素
    public static <T> void printArray(T[] array) {
        for (T element : array) {
            System.out.println(element);
        }
    }

    public static void main(String[] args) {
        // 创建一个字符串数组
        String[] stringArray = {"Apple", "Banana", "Orange"};
        printArray(stringArray); // 调用泛型方法

        // 创建一个整型数组
        Integer[] intArray = {1, 2, 3, 4, 5};
        printArray(intArray); // 调用泛型方法
    }
}

输出结果

Apple
Banana
Orange
1
2
3
4
5

泛型接口

泛型接口是指在接口定义时使用类型参数的接口。以下是一个泛型接口的示例:

// 定义一个泛型接口
interface Pair<K, V> {
    K getKey();
    V getValue();
}

// 实现泛型接口
class OrderedPair<K, V> implements Pair<K, V> {
    private K key;
    private V value;

    public OrderedPair(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public K getKey() {
        return key;
    }

    public V getValue() {
        return value;
    }
}

// 使用泛型接口
public class GenericInterfaceExample {
    public static void main(String[] args) {
        Pair<String, Integer> pair = new OrderedPair<>("One", 1);
        System.out.println("Key: " + pair.getKey() + ", Value: " + pair.getValue());
    }
}

输出结果

Key: One, Value: 1

注意事项

  1. 类型参数的命名:通常使用单个大写字母表示类型参数,如 T(类型)、K(键)、V(值)等。

  2. 不能使用基本数据类型:泛型只能使用对象类型,不能使用基本数据类型(如 intchar 等),可以使用其包装类(如 IntegerCharacter 等)。

  3. 类型擦除:Java 的泛型在编译时会进行类型擦除,运行时不保留泛型信息,因此不能使用 instanceof 检查泛型类型。

泛型是 Java 中非常强大且灵活的特性,能够提高代码的可读性和可维护性。

数据工具类Arrays

Arrays 类

java.util.Arrays 是 Java 集合框架中的一个工具类,提供了一系列静态方法用于操作数组。它包含了用于数组排序、搜索、比较等操作的方法。

常用方法

排序

  • public static void sort(int[] a):对指定的 int 数组进行升序排序。

  • public static void sort(Object[] a):对指定的对象数组进行升序排序,要求数组中的元素实现了 Comparable 接口。

  • public static <T> void sort(T[] a, Comparator<? super T> c):对指定的对象数组进行排序,使用指定的比较器。

搜索

  • public static int binarySearch(int[] a, int key):在指定的 int 数组中使用二分搜索算法搜索指定的值。

  • public static int binarySearch(Object[] a, Object key):在指定的对象数组中使用二分搜索算法搜索指定的值,要求数组中的元素实现了 Comparable 接口。

  • public static <T> int binarySearch(T[] a, T key, Comparator<? super T> c):在指定的对象数组中使用二分搜索算法搜索指定的值,使用指定的比较器。

比较

  • public static boolean equals(int[] a, int[] a2):比较两个 int 数组是否相等。

  • public static boolean equals(Object[] a, Object[] a2):比较两个对象数组是否相等。

示例代码

排序示例

import java.util.Arrays;

public class ArraysExample {
    public static void main(String[] args) {
        int[] numbers = {5, 3, 9, 1, 7};
        Arrays.sort(numbers);
        System.out.println("Sorted numbers: " + Arrays.toString(numbers));

        String[] names = {"Alice", "Bob", "Charlie", "David"};
        Arrays.sort(names);
        System.out.println("Sorted names: " + Arrays.toString(names));
    }
}

搜索示例

import java.util.Arrays;

public class ArraysSearchExample {
    public static void main(String[] args) {
        int[] numbers = {5, 3, 9, 1, 7};
        Arrays.sort(numbers);
        int index = Arrays.binarySearch(numbers, 3);
        System.out.println("Index of 3: " + index);

        String[] names = {"Alice", "Bob", "Charlie", "David"};
        Arrays.sort(names);
        index = Arrays.binarySearch(names, "Bob");
        System.out.println("Index of Bob: " + index);
    }
}

比较示例

import java.util.Arrays;

public class ArraysEqualsExample {
    public static void main(String[] args) {
        int[] numbers1 = {1, 2, 3};
        int[] numbers2 = {1, 2, 3};
        System.out.println("Are numbers1 and numbers2 equal? " + Arrays.equals(numbers1, numbers2));

        String[] names1 = {"Alice", "Bob", "Charlie"};
        String[] names2 = {"Alice", "Bob", "Charlie"};
        System.out.println("Are names1 and names2 equal? " + Arrays.equals(names1, names2));
    }
}

在上述示例中,我们演示了 Arrays 类的排序、搜索和比较操作。通过调用 sort 方法对数组进行排序,使用 binarySearch 方法进行搜索,以及使用 equals 方法比较数组是否相等。

集合工具类Collections

Collections 类

java.util.Collections 是 Java 集合框架中的一个工具类,提供了一系列静态方法,用于对集合进行各种操作,如排序、查找、替换等。Collections 类中的方法都是静态的,可以直接通过类名调用。

常用方法

排序

  • sort(List<T> list):对列表进行排序,要求列表中的元素必须实现 Comparable 接口。

  • sort(List<T> list, Comparator<? super T> c):对列表进行排序,使用自定义的比较器进行排序。

查找和替换

  • binarySearch(List<? extends Comparable<? super T>> list, T key):使用二分查找算法在有序列表中查找指定元素。

  • replaceAll(List<T> list, T oldVal, T newVal):将列表中所有的旧元素替换为新元素。

同步控制

  • synchronizedCollection(Collection<T> c):返回指定集合的同步(线程安全)视图。

  • synchronizedList(List<T> list):返回指定列表的同步(线程安全)视图。

不可变集合

  • unmodifiableCollection(Collection<? extends T> c):返回指定集合的不可变视图。

  • unmodifiableList(List<? extends T> list):返回指定列表的不可变视图。

其他

  • reverse(List<?> list):反转列表中元素的顺序。

  • shuffle(List<?> list):随机打乱列表中元素的顺序。

  • copy(List<? super T> dest, List<? extends T> src):将源列表中的元素复制到目标列表中。

示例代码

排序示例

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

public class CollectionsExample {
    public static void main(String[] args) {
        // 创建一个整型列表
        List<Integer> numbers = new ArrayList<>();
        numbers.add(5);
        numbers.add(2);
        numbers.add(8);
        numbers.add(3);

        // 对列表进行排序
        Collections.sort(numbers);
        System.out.println("排序后的列表:" + numbers);
    }
}

查找和替换示例

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

public class CollectionsExample {
    public static void main(String[] args) {
        // 创建一个字符串列表
        List<String> names = new ArrayList<>();
        names.add("Alice");
        names.add("Bob");
        names.add("Charlie");
        names.add("David");

        // 在有序列表中查找指定元素
        int index = Collections.binarySearch(names, "Charlie");
        System.out.println("元素 Charlie 的索引位置:" + index);

        // 将列表中所有的旧元素替换为新元素
        Collections.replaceAll(names, "Bob", "Eve");
        System.out.println("替换后的列表:" + names);
    }
}

同步控制示例

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

public class CollectionsExample {
    public static void main(String[] args) {
        // 创建一个字符串列表
        List<String> colors = new ArrayList<>();
        colors.add("Red");
        colors.add("Green");
        colors.add("Blue");

        // 获取同步视图
        List<String> synchronizedColors = Collections.synchronizedList(colors);

        // 在同步视图上进行安全操作
        synchronized (synchronizedColors) {
            for (String color : synchronizedColors) {
                System.out.println(color);
            }
        }
    }
}

不可变集合示例

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

public class CollectionsExample {
    public static void main(String[] args) {
        // 创建一个整型列表
        List<Integer> originalList = new ArrayList<>();
        originalList.add(1);
        originalList.add(2);
        originalList.add(3);

        // 获取不可变视图
        List<Integer> unmodifiableList = Collections.unmodifiableList(originalList);

        // 尝试修改不可变视图
        // unmodifiableList.add(4); // 会抛出 UnsupportedOperationException 异常
    }
}

其他示例

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

public class CollectionsExample {
    public static void main(String[] args) {
        // 创建一个整型列表
        List<Integer> numbers = new ArrayList<>();
        numbers.add(1);
        numbers.add(2);
        numbers.add(3);
        numbers.add(4);

        // 反转列表中元素的顺序
        Collections.reverse(numbers);
        System.out.println("反转后的列表:" + numbers);

        // 随机打乱列表中元素的顺序
        Collections.shuffle(numbers);
        System.out.println("打乱后的列表:" + numbers);
    }
}

以上示例代码演示了 Collections 类中部分常用方法的使用,包括排序、查找和替换、同步控制、不可变集合、反转和打乱等操作。通过 Collections 类提供的丰富功能,可以方便地对集合进行各种操作,提高代码的效率和可维护性。

比较器Comparable和Comparator

在Java中,ComparableComparator是用于对象排序的两个接口。它们的主要区别在于实现方式和使用场景。

Comparable 接口

Comparable接口用于定义对象的自然排序。实现该接口的类需要重写compareTo方法,该方法用于比较当前对象与指定对象的大小关系。

特点

  • 自然排序:实现Comparable接口的类可以直接进行排序。

  • 单一排序方式:每个类只能有一个自然排序方式。

示例代码

class Student implements Comparable<Student> {
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public int compareTo(Student other) {
        // 按年龄升序排序
        return Integer.compare(this.age, other.age);
    }

    @Override
    public String toString() {
        return name + " (" + age + ")";
    }
}

public class ComparableExample {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("Alice", 20));
        students.add(new Student("Bob", 22));
        students.add(new Student("Charlie", 21));

        // 使用 Collections.sort() 进行排序
        Collections.sort(students);

        // 输出排序结果
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

输出结果

Alice (20)
Charlie (21)
Bob (22)

Comparator 接口

Comparator接口用于定义对象的自定义排序。实现该接口的类需要重写compare方法,该方法用于比较两个对象的大小关系。

特点

  • 自定义排序:可以根据需要定义多种排序方式。

  • 灵活性:可以在不修改类的情况下对对象进行排序。

示例代码

class Student {
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return name + " (" + age + ")";
    }
}

class AgeComparator implements Comparator<Student> {
    @Override
    public int compare(Student s1, Student s2) {
        // 按年龄升序排序
        return Integer.compare(s1.getAge(), s2.getAge());
    }
}

class NameComparator implements Comparator<Student> {
    @Override
    public int compare(Student s1, Student s2) {
        // 按姓名字母顺序排序
        return s1.getName().compareTo(s2.getName());
    }
}

public class ComparatorExample {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("Alice", 20));
        students.add(new Student("Bob", 22));
        students.add(new Student("Charlie", 21));

        // 按年龄排序
        Collections.sort(students, new AgeComparator());
        System.out.println("按年龄排序:");
        for (Student student : students) {
            System.out.println(student);
        }

        // 按姓名排序
        Collections.sort(students, new NameComparator());
        System.out.println("按姓名排序:");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

输出结果

按年龄排序:
Alice (20)
Charlie (21)
Bob (22)
按姓名排序:
Alice (20)
Bob (22)
Charlie (21)

总结

  • Comparable接口用于定义对象的自然排序,适用于单一排序方式。

  • Comparator接口用于定义自定义排序,适用于多种排序方式。