Iteration over Set ใน Java
Set เป็น Collection ที่ไม่มีค่าซ้ำ และไม่มีลำดับที่รับประกัน (ยกเว้น LinkedHashSet/TreeSet) การ Iterate ทำได้หลายวิธี
ตัวอย่างที่ 1: for-each Loop (Enhanced For Loop)
import java.util.Set;
import java.util.HashSet;
public class Demo {
public static void main(String[] args) {
System.out.println("The required packages have been imported");
Set inputSet = new HashSet<>();
inputSet.add("Java");
inputSet.add("Scala");
inputSet.add("Python");
inputSet.add("Mysql");
System.out.println("The set is defined as: " + inputSet);
System.out.println("\nIterating over Set using for-each loop:");
for (String element : inputSet) {
System.out.print(element + ", ");
}
}
}
ผลลัพธ์
The required packages have been imported
The set is defined as: [Java, Scala, Mysql, Python]
Iterating over Set using for-each loop:
Java, Scala, Mysql, Python,
ตัวอย่างที่ 2: แยกเป็นเมธอด (OOP)
import java.util.Set;
import java.util.HashSet;
public class Demo {
static void printSet(Set inputSet) {
System.out.println("\nIterating over Set using for-each loop:");
for (String element : inputSet) {
System.out.print(element + ", ");
}
}
public static void main(String[] args) {
System.out.println("The required packages have been imported");
Set inputSet = new HashSet<>();
inputSet.add("Java");
inputSet.add("Scala");
inputSet.add("Python");
inputSet.add("Mysql");
System.out.println("The set is defined as: " + inputSet);
printSet(inputSet);
}
}
วิธี Iterate อื่นๆ
1. Iterator (Explicit)
Iterator iterator = inputSet.iterator();
while (iterator.hasNext()) {
String element = iterator.next();
System.out.print(element + ", ");
// สามารถลบระหว่าง Iterate ได้ปลอดภัย
// iterator.remove();
}
2. Java 8+ forEach() + Lambda
inputSet.forEach(element -> System.out.print(element + ", "));
// หรือ Method Reference
inputSet.forEach(System.out::print); // ต้องจัดการ comma เอง
3. Java 8+ Stream API
// Sequential
inputSet.stream().forEach(System.out::print);
// Parallel (สำหรับ Set ใหญ่)
inputSet.parallelStream().forEach(System.out::print);
4. แปลงเป็น Array แล้ว Iterate
String[] array = inputSet.toArray(new String[0]);
for (String s : array) {
System.out.print(s + ", ");
}
การ Iterate พร้อม Index (ถ้าต้องการ)
Set ไม่มี Index โดยตรง ต้องนับเอง:
int index = 0;
for (String element : inputSet) {
System.out.println(index + ": " + element);
index++;
}
// หรือใช้ Stream กับ index
IntStream.range(0, inputSet.size())
.forEach(i -> System.out.println(i + ": " + inputSet.toArray()[i]));
การลบขณะ Iterate (Safe Removal)
// ❌ ผิด - ConcurrentModificationException
for (String s : set) {
if (s.equals("Java")) set.remove(s);
}
// ✅ ถูก - ใช้ Iterator
Iterator it = set.iterator();
while (it.hasNext()) {
if (it.next().equals("Java")) {
it.remove(); // Safe
}
}
// ✅ Java 8+ - removeIf
set.removeIf(s -> s.equals("Java"));
Set Types และลำดับ Iteration
| Set Type | Iteration Order | Use Case |
|---|---|---|
| HashSet | ไม่ระบุ (Random-ish) | General purpose, เร็วที่สุด |
| LinkedHashSet | ✅ Insertion Order | ต้องการลำดับที่เพิ่มเข้าไป |
| TreeSet | ✅ Sorted (Natural/Comparator) | ต้องการเรียงลำดับ |
| EnumSet | Enum Declaration Order | Enum values เท่านั้น, เร็วมาก |
| CopyOnWriteArraySet | Snapshot at iterator creation | Thread-safe iteration |
Best Practices
- ใช้ for-each สำหรับการอ่านอย่างง่าย (Read-only)
- ใช้ Iterator เมื่อต้องลบขณะ Iterate
- ใช้ removeIf() (Java 8+) สำหรับลบแบบเงื่อนไข
- ใช้ Stream เมื่อต้องการ Filter/Map/Collect
- เลือก Set Implementation ให้เหมาะสมกับความต้องการลำดับ
สรุป
- for-each loop: ง่ายที่สุด สำหรับ Read-only
- Iterator: เมื่อต้อง Remove ระหว่าง Loop
- forEach/Stream: Functional style, Java 8+
- LinkedHashSet: รักษาลำดับ Insertion
- TreeSet: เรียงลำดับอัตโนมัติ