2011-07-18 37 views
8

Đây là một câu hỏi khá phổ biến, nhưng tôi không thể tìm thấy phần này:Cách tìm bản sao trong một ArrayList <Object>?

Nói rằng tôi có danh sách mảng này:

List<MyDataClass> arrayList = new List<MyDataClass>; 

MyDataClass{ 
    String name; 
    String age; 
} 

Bây giờ, tôi cần phải tìm bản sao trên cơ sở age trong MyDataClass và loại bỏ chúng. Làm thế nào là nó có thể sử dụng một cái gì đó như HashSet như mô tả here?

Tôi đoán, chúng tôi sẽ cần ghi đè equals trong MyDataClass?

  1. Nhưng, nếu tôi không có sự sang trọng để làm điều đó thì sao?
  2. Và HashSet thực sự tìm kiếm nội bộ như thế nào và không thêm bản sao? Tôi thấy nó thực hiện here in OpenJDK nhưng không thể hiểu được.

Trả lời

14

tôi muốn đề nghị rằng bạn ghi đè cảequalshashCode (HashSet dựa trên cả hai!)

Để loại bỏ các bản sao bạn chỉ có thể tạo ra một mới HashSet với ArrayList như là đối số, và sau đó rõ ràng ArrayList và đặt lại các phần tử được lưu trữ trong HashSet.

class MyDataClass { 
    String name; 
    String age; 

    @Override 
    public int hashCode() { 
     return name.hashCode()^age.hashCode(); 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (!(obj instanceof MyDataClass)) 
      return false; 

     MyDataClass mdc = (MyDataClass) obj; 
     return mdc.name.equals(name) && mdc.age.equals(age); 
    } 
} 

Và sau đó làm

List<MyDataClass> arrayList = new ArrayList<MyDataClass>(); 

Set<MyDataClass> uniqueElements = new HashSet<MyDataClass>(arrayList); 
arrayList.clear(); 
arrayList.addAll(uniqueElements); 

Nhưng, những gì nếu tôi không có sự sang trọng của làm điều đó?

Sau đó, tôi muốn đề nghị bạn làm một số loại trang trí lớp học mà không cung cấp các phương pháp này.

class MyDataClassDecorator { 

    MyDataClass mdc; 

    public MyDataClassDecorator(MyDataClass mdc) { 
     this.mdc = mdc; 
    } 

    @Override 
    public int hashCode() { 
     return mdc.name.hashCode()^mdc.age.hashCode(); 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (!(obj instanceof MyDataClassDecorator)) 
      return false; 

     MyDataClassDecorator mdcd = (MyDataClassDecorator) obj; 
     return mdcd.mdc.name.equals(mdc.name) && mdcd.mdc.age.equals(mdc.age); 
    } 
} 
+2

Tôi tự hỏi nếu OP muốn bình đẳng cơ sở * chỉ * trên tuổi thay vì cả tên và tuổi ... đó là cách đọc câu hỏi. Ngoài ra, +1. – Jonik

+0

Đúng. Tôi sẽ để nó như một bài tập ;-) – aioobe

1

Và nếu bạn không thể ghi đè "MyDataClass" 's hashCode và equals phương pháp bạn có thể viết một lớp wrapper để xử lý này.

1

xin vui lòng xem article này giải thích tầm quan trọng của equals()hashCode-HashSets

Ngoài ra, thấy điều này trước đây đã trả lời question

0
public Set<Object> findDuplicates(List<Object> list) { 
     Set<Object> items = new HashSet<Object>(); 
     Set<Object> duplicates = new HashSet<Object>(); 
     for (Object item : list) { 
      if (items.contains(item)) { 
       duplicates.add(item); 
       } else { 
        items.add(item); 
        } 
      } 
     return duplicates; 
     } 
Các vấn đề liên quan