# 25. Java 21 新特性 SequencedCollection 如何影响 List 操作?

# 标准答案

SequencedCollectionJava 21 引入的新接口,专门为 ListSetMap 提供 顺序访问能力,增强了双端操作的能力,使 List 处理首尾元素更加直观。
它的主要影响包括:

  1. 新增 getFirst()getLast() 方法,简化 List 访问首尾元素的操作。
  2. 增强 addFirst()addLast() 方法,支持直接向 List 头尾插入元素。
  3. 新增 reversed() 方法,高效获取 List 的反转视图,避免复制开销。
  4. 统一顺序访问接口ArrayListLinkedListList 结构可以直接使用这些方法,而不再需要 Deque 等辅助接口。

# 答案解析

# 1. SequencedCollection 介绍

SequencedCollection 统一了 ListSetMap 的顺序访问,使它们拥有一致的首尾访问顺序反转能力。
其关键方法:

public interface SequencedCollection<E> extends Collection<E> {
    E getFirst();
    E getLast();
    void addFirst(E e);
    void addLast(E e);
    SequencedCollection<E> reversed();
}
1
2
3
4
5
6
7

可以看到,这些方法在 List 操作中非常常见,Java 21 之前,我们需要额外的逻辑才能实现类似功能。

# 2. 影响 List 操作的核心特性

  • 访问首尾元素
List<String> list = new ArrayList<>(List.of("A", "B", "C"));
System.out.println(list.getFirst()); // A
System.out.println(list.getLast());  // C
1
2
3
  • 在首尾插入元素
list.addFirst("X");
list.addLast("Z");
System.out.println(list); // [X, A, B, C, Z]
1
2
3

相比于 list.add(0, element)addFirst() 语义更清晰,也避免了 LinkedList 特有的 offerFirst()/push() 方法的混乱。

  • 反转 List(无需复制)
SequencedCollection<String> reversedList = list.reversed();
System.out.println(reversedList); // [Z, C, B, A, X]
1
2

这里 reversed() 不会创建新 List,而是返回一个反转视图,避免了 Collections.reverse() 需要修改原 Liststream().sorted() 需要额外空间的问题。

# 3. 解决的问题

在 Java 21 之前:

  • 获取 List 头尾元素复杂list.get(0) / list.get(list.size() - 1) 可读性差,且 LinkedListpeekFirst()/peekLast()
  • 插入 List 头尾不直观add(0, element) 影响 ArrayList 性能,而 LinkedListaddFirst()
  • List 反转开销大Collections.reverse() 会修改原 Liststream().sorted() 需额外存储。

SequencedCollection 统一了这些操作,使 List 处理顺序更加一致。

# 4. SequencedCollectionDeque 对比

方法 SequencedCollection Deque
访问首尾元素 getFirst()/getLast() peekFirst()/peekLast()
插入首尾 addFirst()/addLast() offerFirst()/offerLast()
删除首尾 removeFirst()/removeLast() pollFirst()/pollLast()
反转 reversed()(高效视图) 需手动遍历
  • Deque 更适合 双端队列(FIFO、LIFO)场景,如 LinkedListArrayDeque
  • SequencedCollection 适用于 顺序集合,如 List,提供更自然的 API 体验。

# 最佳实践

  1. List 结构中,使用 getFirst()/getLast() 代替 get(0)/get(size-1),提升可读性。
  2. 使用 addFirst()/addLast() 替代 add(0, element),避免 ArrayList 频繁移动元素的性能问题。
  3. 对于大规模 List 反转操作,优先使用 reversed(),避免 Collections.reverse() 带来的修改副作用。

# 深入追问

  • SequencedCollectionLinkedHashSetTreeMap 中如何使用?
  • List.reversed() 如何实现高效反转视图,而不是复制?
  • 为什么 SequencedCollection 没有提供 removeFirst() / removeLast() 方法?

# 相关面试题

  • SequencedCollection 主要解决了 List 结构中的哪些痛点?
  • SequencedCollection 为什么适合 ArrayList 但不适用于 HashSet
  • List.reversed()Collections.reverse() 有何区别?