# 25. Java 21 新特性 SequencedCollection
如何影响 List
操作?
# 标准答案
SequencedCollection
是 Java 21 引入的新接口,专门为 List
、Set
和 Map
提供 顺序访问能力,增强了双端操作的能力,使 List
处理首尾元素更加直观。
它的主要影响包括:
- 新增
getFirst()
和getLast()
方法,简化List
访问首尾元素的操作。 - 增强
addFirst()
和addLast()
方法,支持直接向List
头尾插入元素。 - 新增
reversed()
方法,高效获取List
的反转视图,避免复制开销。 - 统一顺序访问接口,
ArrayList
、LinkedList
等List
结构可以直接使用这些方法,而不再需要Deque
等辅助接口。
# 答案解析
# 1. SequencedCollection
介绍
SequencedCollection
统一了 List
、Set
、Map
的顺序访问,使它们拥有一致的首尾访问和顺序反转能力。
其关键方法:
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
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
2
3
- 在首尾插入元素
list.addFirst("X");
list.addLast("Z");
System.out.println(list); // [X, A, B, C, Z]
1
2
3
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
2
这里 reversed()
不会创建新 List
,而是返回一个反转视图,避免了 Collections.reverse()
需要修改原 List
或 stream().sorted()
需要额外空间的问题。
# 3. 解决的问题
在 Java 21 之前:
- 获取
List
头尾元素复杂,list.get(0)
/list.get(list.size() - 1)
可读性差,且LinkedList
需peekFirst()/peekLast()
。 - 插入
List
头尾不直观,add(0, element)
影响ArrayList
性能,而LinkedList
需addFirst()
。 List
反转开销大,Collections.reverse()
会修改原List
,stream().sorted()
需额外存储。
SequencedCollection
统一了这些操作,使 List
处理顺序更加一致。
# 4. SequencedCollection
与 Deque
对比
方法 | SequencedCollection | Deque |
---|---|---|
访问首尾元素 | getFirst()/getLast() | peekFirst()/peekLast() |
插入首尾 | addFirst()/addLast() | offerFirst()/offerLast() |
删除首尾 | removeFirst()/removeLast() | pollFirst()/pollLast() |
反转 | reversed() (高效视图) | 需手动遍历 |
Deque
更适合 双端队列(FIFO、LIFO)场景,如LinkedList
、ArrayDeque
。SequencedCollection
适用于 顺序集合,如List
,提供更自然的 API 体验。
# 最佳实践
- 在
List
结构中,使用getFirst()/getLast()
代替get(0)/get(size-1)
,提升可读性。 - 使用
addFirst()/addLast()
替代add(0, element)
,避免ArrayList
频繁移动元素的性能问题。 - 对于大规模
List
反转操作,优先使用reversed()
,避免Collections.reverse()
带来的修改副作用。
# 深入追问
SequencedCollection
在LinkedHashSet
和TreeMap
中如何使用?List.reversed()
如何实现高效反转视图,而不是复制?- 为什么
SequencedCollection
没有提供removeFirst()
/removeLast()
方法?
# 相关面试题
SequencedCollection
主要解决了List
结构中的哪些痛点?SequencedCollection
为什么适合ArrayList
但不适用于HashSet
?List.reversed()
和Collections.reverse()
有何区别?