Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

Java Program ลบสมาชิกซ้ำใน ArrayList (Remove Duplicates)

การลบ 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()