ListIterator และการวนดูแบบสองทิศทาง
ใช้ ListIterator วนดูรายการไปข้างหน้าและย้อนกลับ พร้อมแก้ไของค์ประกอบระหว่างการวนซ้ำ
ListIterator และการวนดูแบบสองทิศทาง เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
ListIterator
ListIterator<T> ขยายความสามารถจาก Iterator<T> ด้วยการท่องย้อนกลับ การระบุตำแหน่งตามดัชนี และความสามารถในการเพิ่มและแทนที่สมาชิกระหว่างการวนซ้ำ
API ของ ListIterator
เมธอดเพิ่มเติมนอกเหนือจากตัววนซ้ำ ได้แก่ hasPrevious(), previous(), nextIndex(), previousIndex(), set() และ add()
import java.util.*;
List<String> list = new ArrayList<>(List.of("A", "B", "C", "D"));
ListIterator<String> lit = list.listIterator();
// Forward traversal
while (lit.hasNext()) {
System.out.print(lit.nextIndex() + ":" + lit.next() + " ");
}
// 0:A 1:B 2:C 3:D
System.out.println();
// Backward traversal
while (lit.hasPrevious()) {
System.out.print(lit.previousIndex() + ":" + lit.previous() + " ");
}
// 3:D 2:C 1:B 0:Aการเริ่มต้นที่ตำแหน่งหนึ่ง
สร้าง ListIterator โดยเริ่มต้นที่ดัชนีที่ระบุด้วย listIterator(index)
List<Integer> nums = new ArrayList<>(List.of(10, 20, 30, 40, 50));
// Start at index 2 (30)
ListIterator<Integer> lit = nums.listIterator(2);
System.out.println(lit.next()); // 30
System.out.println(lit.next()); // 40
System.out.println(lit.previous()); // 40
System.out.println(lit.previous()); // 30
System.out.println(lit.previous()); // 20การใช้ set() ระหว่างการวนซ้ำ
set() จะแทนที่องค์ประกอบล่าสุดที่ส่งคืนโดย next() หรือ previous() การดำเนินการนี้มีประสิทธิภาพ โดยใช้เวลา O(1) สำหรับ LinkedList และ O(1) สำหรับ ArrayList
List<String> words = new ArrayList<>(List.of("hello", "world", "java"));
ListIterator<String> lit = words.listIterator();
while (lit.hasNext()) {
String word = lit.next();
lit.set(word.toUpperCase()); // replace each with uppercase
}
System.out.println(words); // [HELLO, WORLD, JAVA]การใช้ add() ระหว่างการวนซ้ำ
add(element) จะแทรกองค์ประกอบก่อนตำแหน่งถัดไป องค์ประกอบที่เพิ่มจะไม่ถูกส่งคืนโดยการเรียก next() ในครั้งถัดไป เพราะองค์ประกอบนั้นอยู่ "ด้านหลัง" เคอร์เซอร์แล้ว
List<Integer> numbers = new ArrayList<>(List.of(1, 2, 3));
ListIterator<Integer> lit = numbers.listIterator();
while (lit.hasNext()) {
int n = lit.next();
lit.add(n * 10); // insert n*10 after each element
}
System.out.println(numbers); // [1, 10, 2, 20, 3, 30]การกลับลำดับรายการภายในรายการเดิม
ใช้ ListIterator เพื่อกลับลำดับรายการด้วยเวลา O(n) โดยไม่ต้องจัดสรรรายการใหม่
static <T> void reverse(List<T> list) {
ListIterator<T> front = list.listIterator(0);
ListIterator<T> back = list.listIterator(list.size());
for (int i = 0, n = list.size() / 2; i < n; i++) {
T frontVal = front.next();
T backVal = back.previous();
front.set(backVal);
back.set(frontVal);
}
}
List<String> data = new ArrayList<>(List.of("a","b","c","d","e"));
reverse(data);
System.out.println(data); // [e, d, c, b, a]nextIndex และ previousIndex
nextIndex() ส่งคืนดัชนีขององค์ประกอบที่จะถูกส่งคืนโดย next() ส่วน previousIndex() ส่งคืนดัชนีขององค์ประกอบที่จะถูกส่งคืนโดย previous()
List<String> list = List.of("X", "Y", "Z");
ListIterator<String> lit = list.listIterator();
System.out.println(lit.nextIndex()); // 0
System.out.println(lit.previousIndex()); // -1 (before start)
lit.next(); // consume X
System.out.println(lit.nextIndex()); // 1
System.out.println(lit.previousIndex()); // 0ประสิทธิภาพของ LinkedList ListIterator
ListIterator ของ LinkedList ทำให้ next/previous ใช้เวลา O(1) เพราะการเคลื่อนที่เป็นการติดตามตัวชี้ ส่วน get(i) บน LinkedList ใช้เวลา O(n) ดังนั้นควรใช้ ListIterator เพื่อเคลื่อนที่ผ่านรายการอย่างมีประสิทธิภาพ
import java.util.*;
LinkedList<Integer> list = new LinkedList<>();
for (int i = 0; i < 5; i++) list.add(i * 10);
// Efficient: O(n) total for traversal via ListIterator
ListIterator<Integer> lit = list.listIterator();
while (lit.hasNext()) {
int val = lit.next();
if (val == 20) lit.set(99); // O(1) update
}
System.out.println(list); // [0, 10, 99, 30, 40]การตรวจสอบพาลินโดรมด้วย ListIterator
ตัวอย่างที่สง่างามของการเคลื่อนที่สองทิศทาง: การตรวจสอบว่ารายการเป็นพาลินโดรมหรือไม่
static <T> boolean isPalindrome(List<T> list) {
ListIterator<T> front = list.listIterator(0);
ListIterator<T> back = list.listIterator(list.size());
for (int i = 0, n = list.size() / 2; i < n; i++) {
if (!front.next().equals(back.previous())) return false;
}
return true;
}
System.out.println(isPalindrome(List.of(1, 2, 3, 2, 1))); // true
System.out.println(isPalindrome(List.of(1, 2, 3, 4))); // falseการเปรียบเทียบ Iterator กับ ListIterator
ความแตกต่างสำคัญ:
- ตัววนซ้ำ: เดินหน้าได้ทิศทางเดียว มี hasNext/next/remove
- ListIterator: เดินทางได้สองทิศทาง มี hasPrevious/previous, nextIndex/previousIndex และ set/add
- ListIterator ใช้ได้เฉพาะกับรายการ ไม่ใช่ Set หรือ Queue
การเลิกทำและทำซ้ำด้วย ListIterator
ตัวแก้ไขข้อความที่ใช้เคอร์เซอร์และ ListIterator เพื่อเลื่อนดูอักขระสำหรับการเลิกทำและทำซ้ำอย่างมีประสิทธิภาพ
import java.util.*;
class TextEditor {
private final LinkedList<Character> chars = new LinkedList<>();
private ListIterator<Character> cursor;
TextEditor() { cursor = chars.listIterator(); }
void type(char c) { cursor.add(c); } // insert before cursor
void moveCursorLeft() { if (cursor.hasPrevious()) cursor.previous(); }
void moveCursorRight() { if (cursor.hasNext()) cursor.next(); }
void backspace() {
if (cursor.hasPrevious()) { cursor.previous(); cursor.remove(); }
}
String text() {
StringBuilder sb = new StringBuilder();
chars.forEach(sb::append);
return sb.toString();
}
}
TextEditor ed = new TextEditor();
ed.type('H'); ed.type('e'); ed.type('l'); ed.type('o');
ed.moveCursorLeft(); ed.moveCursorLeft();
ed.type('l');
System.out.println(ed.text()); // Helloเวลาที่ควรใช้ ListIterator
ควรใช้ ListIterator เมื่อจำเป็นต้อง:
- เคลื่อนที่ย้อนกลับผ่านรายการ
- แทนที่องค์ประกอบระหว่างการเคลื่อนที่ด้วย set()
- แทรกองค์ประกอบระหว่างการเคลื่อนที่ด้วย add()
- ติดตามตำแหน่งผ่าน nextIndex()/previousIndex()
ตรวจสอบความเข้าใจอย่างรวดเร็ว
ListIterator.set() ทำหน้าที่อะไร
สรุป: ListIterator และการเคลื่อนที่สองทิศทาง
ประเด็นสำคัญ:
- ListIterator สืบทอดความสามารถจากตัววนซ้ำ พร้อมมี hasPrevious(), previous(), set() และ add()
- สร้าง ListIterator ที่ตำแหน่งเฉพาะได้ด้วย listIterator(index)
- set() จะแทนที่องค์ประกอบล่าสุดที่ next() หรือ previous() ส่งคืน
- add() จะแทรกองค์ประกอบก่อนตำแหน่งปัจจุบันของเคอร์เซอร์
- nextIndex() และ previousIndex() ให้ข้อมูลเกี่ยวกับตำแหน่ง
- ใช้ LinkedList ListIterator เพื่อการเคลื่อนที่และแก้ไขที่ใช้เวลา O(1)
คำถามที่พบบ่อย
บทเรียน “ListIterator และการวนดูแบบสองทิศทาง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ListIterator และการวนดูแบบสองทิศทาง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ListIterator และการวนดูแบบสองทิศทาง”
ใช้ ListIterator วนดูรายการไปข้างหน้าและย้อนกลับ พร้อมแก้ไของค์ประกอบระหว่างการวนซ้ำ คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “ListIterator และการวนดูแบบสองทิศทาง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม
ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- สัญญาของ Iterable และ Iterator
- การสร้าง Iterator แบบกำหนดเอง
- ListIterator และการวนดูแบบสองทิศทาง
- Iterator แบบหยุดเร็วกับแบบปลอดภัย