
SequencedCollection: เข้าถึงหัว-ท้ายและมุมกลับในชุดที่มีลำดับ
น้องกายEngineering
เคยต้องเขียน list.get(0) กับ list.get(list.size()-1) คนละสไตล์กับ Deque ไหม ผมเคย จนเจอ Sequenced Collections
ตั้งแต่ Java 21 ตามเอกสาร API ของ SequencedCollection คอลเลกชันที่มีลำดับการพบ (encounter order) ได้เมธอดหัว-ท้ายแบบเดียวกัน และมี reversed() เป็นมุมมองลำดับกลับ
ของที่ควรจำชื่อ
- SequencedCollection:
getFirst/getLast/addFirst/addLast/removeFirst/removeLast/reversed - SequencedSet: เหมือนด้านบนแต่สมาชิกไม่ซ้ำ เช่น
LinkedHashSet - SequencedMap: จัดการแมปปิงหัว-ท้าย เช่น
firstEntry/lastEntry/putFirst/putLast
ตัวอย่างด้านล่างเป็น code fragment สำหรับ JDK 21 ขึ้นไป จึงไม่อ้างว่ารันบน JDK 17 ของ quality gate แล้ว
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.SequencedCollection;
import java.util.SequencedMap;
import java.util.SequencedSet;
public class Main {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.addFirst("a");
list.addLast("c");
list.add(1, "b");
SequencedCollection<String> sequenced = list;
if (!"a".equals(sequenced.getFirst()) || !"c".equals(sequenced.getLast())) {
throw new IllegalStateException("list ends wrong: " + list);
}
List<String> reversed = sequenced.reversed().stream().toList();
if (!List.of("c", "b", "a").equals(reversed)) {
throw new IllegalStateException("reversed wrong: " + reversed);
}
SequencedSet<String> set = new LinkedHashSet<>();
set.addFirst("one");
set.addLast("two");
set.addLast("three");
if (!List.of("one", "two", "three").equals(List.copyOf(set))) {
throw new IllegalStateException("set order wrong: " + set);
}
if (!"one".equals(set.getFirst()) || !"three".equals(set.getLast())) {
throw new IllegalStateException("set ends wrong: " + set);
}
SequencedMap<String, Integer> map = new LinkedHashMap<>();
map.putFirst("first", 1);
map.putLast("last", 2);
if (!"first".equals(map.firstEntry().getKey()) || !"last".equals(map.lastEntry().getKey())) {
throw new IllegalStateException("map wrong: " + map);
}
System.out.println("sequenced ok " + list + " " + set + " " + map);
}
}
Recap
- ใช้ API หัว-ท้ายชุดเดียวเมื่อคอลเลกชันมีลำดับชัด
- เลือก
SequencedSetเมื่อห้ามซ้ำ และSequencedMapเมื่อสนใจลำดับของแมปปิง - จำว่า
reversed()เป็นมุมมอง มีชีวิต ไม่ใช่สำเนาแยกเสมอไป - ต้อง JDK 21 ขึ้นไปก่อนเรียกเมธอดเหล่านี้