核心结论先行
- 存储顺序:
ArrayList严格保持元素的添加顺序,你先添加的元素,在列表中的索引就小;后添加的,索引就大,这是ArrayList最基本、最重要的特性。 - 排序:
ArrayList本身不提供自动排序功能,如果你需要对列表中的元素进行排序,需要手动调用Collections.sort()方法或List.sort()方法。
存储顺序:保持添加顺序
ArrayList 内部使用一个数组(Object[] elementData)来存储元素,当你向 ArrayList 中添加一个元素时,它会被追加到数组的末尾,这就是它能够保持添加顺序的根本原因。

示例代码
import java.util.ArrayList;
import java.util.List;
public class ArrayListOrderExample {
public static void main(String[] args) {
// 创建一个 ArrayList
List<String> fruits = new ArrayList<>();
// 按照特定顺序添加元素
fruits.add("Banana");
fruits.add("Apple");
fruits.add("Orange");
fruits.add("Grape");
// 打印列表,观察顺序
System.out.println("初始添加顺序: " + fruits);
// 输出: 初始添加顺序: [Banana, Apple, Orange, Grape]
// 通过索引访问元素,验证顺序
System.out.println("索引 0 的元素: " + fruits.get(0)); // Banana
System.out.println("索引 1 的元素: " + fruits.get(1)); // Apple
System.out.println("索引 2 的元素: " + fruits.get(2)); // Orange
System.out.println("索引 3 的元素: " + fruits.get(3)); // Grape
// 在中间插入一个元素
fruits.add(1, "Mango"); // 在索引 1 的位置插入 "Mango"
System.out.println("在索引 1 插入 'Mango' 后: " + fruits);
// 输出: 在索引 1 插入 'Mango' 后: [Banana, Mango, Apple, Orange, Grape]
// 可以看到,"Mango" 被插入到了 "Apple" 的前面,但 "Apple" 及其后面的元素都向后顺延了。
}
}
关键点:
add(E e):将元素e添加到列表的末尾。add(int index, E e):将元素e插入到指定的index位置,该位置及之后的所有元素都会向后移动一位。get(int index):根据索引获取元素,索引从 0 开始,代表了添加的先后顺序。
排序:如何改变顺序
ArrayList 本身是“无序”的(这里的“无序”指没有内置的排序规则,它只关心添加顺序),当你需要按照特定规则(如字母顺序、数字大小等)对列表进行排序时,需要借助 Java 的工具类。
使用 Collections.sort() (适用于 Java 8 之前)
这是最传统、最常用的排序方法,它会原地修改 ArrayList,即直接对原列表进行排序,不返回新列表。
注意:Collections.sort() 要求列表中的元素必须实现 Comparable 接口(如 String, Integer, Double 等基本类型的包装类都已实现),否则会抛出 ClassCastException。

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ArrayListSortExample {
public static void main(String[] args) {
List<String> fruits = new ArrayList<>();
fruits.add("Banana");
fruits.add("Apple");
fruits.add("Orange");
fruits.add("Grape");
System.out.println("排序前: " + fruits);
// 输出: 排序前: [Banana, Apple, Orange, Grape]
// 使用 Collections.sort() 进行自然排序(对于 String 是字典序)
Collections.sort(fruits);
System.out.println("使用 Collections.sort() 排序后: " + fruits);
// 输出: 使用 Collections.sort() 排序后: [Apple, Banana, Grape, Orange]
}
}
使用 List.sort() (Java 8+ 引入)
Java 8 为 List 接口引入了 sort() 方法,它的功能和 Collections.sort() 完全一样,只是调用方式更面向对象,它也需要一个 Comparator 对象。
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class ListSortExample {
public static void main(String[] args) {
List<String> fruits = new ArrayList<>();
fruits.add("Banana");
fruits.add("Apple");
fruits.add("Orange");
fruits.add("Grape");
System.out.println("排序前: " + fruits);
// 输出: 排序前: [Banana, Apple, Orange, Grape]
// 使用 List.sort() 进行自然排序
// Comparator.naturalOrder() 提供了自然排序的比较器
fruits.sort(Comparator.naturalOrder());
System.out.println("使用 List.sort() 排序后: " + fruits);
// 输出: 使用 List.sort() 排序后: [Apple, Banana, Grape, Orange]
}
}
自定义排序
如果你想按照自己的规则排序(按字符串长度排序),可以提供一个自定义的 Comparator。
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class CustomSortExample {
public static void main(String[] args) {
List<String> fruits = new ArrayList<>();
fruits.add("Banana");
fruits.add("Apple");
fruits.add("Orange");
fruits.add("Grape");
System.out.println("排序前: " + fruits);
// 输出: 排序前: [Banana, Apple, Orange, Grape]
// 使用 Lambda 表达式自定义比较器,按字符串长度升序排序
fruits.sort(Comparator.comparingInt(String::length));
System.out.println("按字符串长度排序后: " + fruits);
// 输出: 按字符串长度排序后: [Apple, Grape, Banana, Orange]
// 按字符串长度降序排序
fruits.sort(Comparator.comparingInt(String::length).reversed());
System.out.println("按字符串长度降序排序后: " + fruits);
// 输出: 按字符串长度降序排序后: [Banana, Orange, Apple, Grape]
}
}
与 HashSet 的顺序对比
为了更好地理解 ArrayList 的“保持添加顺序”,我们常常会把它和 HashSet 进行对比。
| 特性 | ArrayList |
HashSet |
|---|---|---|
| 顺序 | 保持添加顺序 (Insertion Order) | 不保证任何顺序 (No Order Guarantee) |
| 底层结构 | 动态数组 | 哈希表 |
| 允许重复 | 是 | 否 |
| 排序方式 | 手动调用 sort() 方法 |
无,可通过 TreeSet 实现排序 |
示例对比
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class OrderComparison {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Set<String> set = new HashSet<>();
// 添加相同的元素
list.add("Banana");
list.add("Apple");
list.add("Orange");
list.add("Grape");
list.add("Apple"); // 重复元素
set.add("Banana");
set.add("Apple");
set.add("Orange");
set.add("Grape");
set.add("Apple"); // 重复元素,不会被添加
System.out.println("ArrayList 的顺序: " + list);
// 输出: ArrayList 的顺序: [Banana, Apple, Orange, Grape, Apple]
// 保持了添加顺序,并且允许重复
System.out.println("HashSet 的顺序: " + set);
// 输出可能是: [Apple, Grape, Banana, Orange] 或其他任何顺序
// 不保证顺序,且不允许重复
}
}
ArrayList的顺序:默认情况下,ArrayList是一个有序列表,它严格维护你添加元素的先后顺序,这是它的核心设计之一。- 如何排序:
ArrayList自身不排序,你需要使用外部工具:Collections.sort(myList);(Java 8 之前)myList.sort(Comparator.naturalOrder());(Java 8+)
- 选择:
- 如果你需要根据索引快速访问元素,并且需要保持元素的添加顺序,请使用
ArrayList。 - 如果你只需要存储不重复的元素,并且不关心它们的存储顺序,请使用
HashSet。 - 如果你需要存储不重复的元素,并且希望它们按照特定规则(如自然顺序)自动排序,请使用
TreeSet。
- 如果你需要根据索引快速访问元素,并且需要保持元素的添加顺序,请使用

