การลบ Duplicate จาก ArrayList
ArrayList อนุญาตค่าซ้ำได้ วิธีง่ายที่สุดคือแปลงเป็น Set (ซึ่งไม่อนุญาต duplicate) แล้วคืนกลับเป็น List
หลักการ: ใช้ LinkedHashSet
HashSet- ไม่รักษาลำดับLinkedHashSet- รักษาลำดับการ Insert (Insertion Order) ⭐ แนะนำTreeSet- เรียงลำดับ (Sorted)
ตัวอย่างที่ 1: ใน main โดยตรง
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
public class Demo {
public static void main(String[] args) {
System.out.println("The required packages have been imported");
ArrayList inputList = new ArrayList<>(
Arrays.asList(150, 250, 300, 250, 500, 150, 600, 750, 300)
);
System.out.println("The list is defined as: " + inputList);
// 1. สร้าง LinkedHashSet (รักษาลำดับ, ไม่ซ้ำ)
Set tempSet = new LinkedHashSet<>();
// 2. เพิ่มทั้งหมดจาก ArrayList เข้า Set
tempSet.addAll(inputList);
// 3. ล้าง ArrayList เดิม
inputList.clear();
// 4. เพิ่มค่าจาก Set กลับเข้า ArrayList
inputList.addAll(tempSet);
System.out.println("\nThe list with no duplicates is: \n" + inputList);
}
}
ผลลัพธ์
The required packages have been imported
The list is defined as: [150, 250, 300, 250, 500, 150, 600, 750, 300]
The list with no duplicates is:
[150, 250, 300, 500, 600, 750]
ตัวอย่างที่ 2: แยกเป็นเมธอด (OOP)
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
public class Demo {
static void removeDuplicates(ArrayList inputList) {
Set tempSet = new LinkedHashSet<>();
tempSet.addAll(inputList);
inputList.clear();
inputList.addAll(tempSet);
System.out.println("\nThe list with no duplicates is: \n" + inputList);
}
public static void main(String[] args) {
System.out.println("The required packages have been imported");
ArrayList inputList = new ArrayList<>(
Arrays.asList(150, 250, 300, 250, 500, 150, 600, 750, 300)
);
System.out.println("The list is defined as: " + inputList);
removeDuplicates(inputList);
}
}
วิธีอื่นๆ (Alternative Approaches)
1. Java 8 Stream API (Distinct)
// สร้าง List ใหม่ (ไม่แก้ไข List เดิม)
List distinctList = inputList.stream()
.distinct()
.collect(Collectors.toList());
// หรือ modify in-place (Java 10+)
inputList = inputList.stream().distinct().collect(Collectors.toCollection(ArrayList::new));
2. ใช้ LinkedHashMap (Java 8+)
// ใช้ key ของ Map เป็นค่าใน List (Value ใส่ dummy)
List distinct = new ArrayList<>(
new LinkedHashMap(
inputList.stream().collect(Collectors.toMap(
v -> v, v -> true, (a, b) -> a, LinkedHashMap::new
))
).keySet()
);
3. Manual Loop (ไม่ใช้ Collection เพิ่ม)
public static void removeDuplicatesManual(ArrayList list) {
for (int i = 0; i < list.size(); i++) {
for (int j = i + 1; j < list.size(); j++) {
if (list.get(i).equals(list.get(j))) {
list.remove(j);
j--; // ปรับดัชนีหลัง remove
}
}
}
}
// Time: O(n²), Space: O(1) - ช้า แต่ไม่ใช้ memory เพิ่ม
เปรียบเทียบวิธีการ
| วิธีการ | Time | Space | รักษาลำดับ | หมายเหตุ |
|---|---|---|---|---|
| LinkedHashSet + addAll | O(n) | O(n) | ✅ | แนะนำ สำหรับ General use |
| Stream.distinct() | O(n) | O(n) | ✅ | Functional style, สร้าง List ใหม่ |
| Manual nested loop | O(n²) | O(1) | ✅ | ไม่ใช้ memory เพิ่ม แตช้า |
| TreeSet + addAll | O(n log n) | O(n) | ❌ (Sorted) | ถ้าต้องการเรียงลำดับด้วย |
สำหรับ Object Types (Custom Objects)
ต้อง Override equals() และ hashCode() ในคลาส:
public class Person {
String name;
int age;
// ต้องมี equals และ hashCode
@Override
public boolean equals(Object o) { ... }
@Override
public int hashCode() { ... }
}
// แล้วค่อยใช้ LinkedHashSet ได้ตามปกติ
สรุป
- วิธีมาตรฐาน: LinkedHashSet + addAll + clear + addAll
- รักษาลำดับเดิม (Insertion Order)
- Time O(n), Space O(n)
- Java 8+: ใช้
stream().distinct()ได้ - Custom Object ต้อง implement equals() และ hashCode()