Java Collections.rotate: หมุนลำดับโดยไม่สร้าง list ใหม่
พี่โชว์Engineering
Collections.rotate เลื่อนสมาชิกใน list แบบ in place: distance บวกไปทางขวา ลบไปทางซ้าย และค่าที่เกินขนาดจะถูกคิดแบบวงกลมครับ เหมือนหมุนถาดซูชิทั้งสาย ไม่ได้ยกอาหารไปวางในถาดใหม่
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] args) {
var values = new ArrayList<>(List.of("A", "B", "C", "D"));
Collections.rotate(values, 1);
assert values.equals(List.of("D", "A", "B", "C"));
Collections.rotate(values, -2);
assert values.equals(List.of("B", "C", "D", "A"));
Collections.rotate(values, 8);
assert values.equals(List.of("B", "C", "D", "A"));
var empty = new ArrayList<String>();
Collections.rotate(empty, 3);
assert empty.isEmpty();
}
}
Mutation เป็นส่วนหนึ่งของ contract
List ต้องรองรับ set; List.of(...) เป็น immutable จึงต้อง copy เป็น ArrayList ก่อน หากผู้เรียกต้องรักษาลำดับเดิม ให้สร้างสำเนาอย่างตั้งใจและตั้งชื่อผลลัพธ์ให้สื่อว่าคือ rotated copy
สำหรับ queue ที่หมุนบ่อย ArrayDeque อาจเหมาะกว่า เพราะย้ายหัวท้ายได้ตรง semantics ส่วน rotate เด่นเมื่อเรามี list อยู่แล้วและต้อง reorder ครั้งคราว
Recap
- บวกหมุนขวา ลบหมุนซ้าย
- distance ถูก normalize ตามขนาด
- ใช้ mutable list เท่านั้น
- เลือก deque หากงานหลักคือหมุนคิวซ้ำ ๆ