杰瑞科技汇

java arraylist 顺序

核心结论先行

  1. 存储顺序ArrayList 严格保持元素的添加顺序,你先添加的元素,在列表中的索引就小;后添加的,索引就大,这是 ArrayList 最基本、最重要的特性。
  2. 排序ArrayList 本身不提供自动排序功能,如果你需要对列表中的元素进行排序,需要手动调用 Collections.sort() 方法或 List.sort() 方法。

存储顺序:保持添加顺序

ArrayList 内部使用一个数组(Object[] elementData)来存储元素,当你向 ArrayList 中添加一个元素时,它会被追加到数组的末尾,这就是它能够保持添加顺序的根本原因。

java arraylist 顺序-图1
(图片来源网络,侵删)

示例代码

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

java arraylist 顺序-图2
(图片来源网络,侵删)
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
java arraylist 顺序-图3
(图片来源网络,侵删)
分享:
扫描分享到社交APP
上一篇
下一篇