2012-07-26 132 views
1

我有2個自定義對象的ArrayList。我想從兩個ArrayList中刪除重複的條目。Java ArrayList從兩個列表中刪除重複項

對象有三個字段:fName,lName和id。如果id多次出現,我想從兩個列表中刪除。

我該怎麼做?

我很好地合併了兩個列表並刪除了兩個重複的條目。

回答

2

如果您想合併:只需將兩個列表的內容複製到地圖。然後,你沒有重複了(但你失去了你的實際排序):

Map<Integer, MyObject> temp = new HashMap<Integer, MyObject>(); 
for (MyObject obj:firstList) { 
    temp.put(obj.getId(), obj); 
} 
for (MyObject obj:secondList) { 
    temp.put(obj.getId(), obj); 
} 
List<MyObject> result = new ArrayList<MyObject>(temp.values()); 
+0

他想從兩個列表中刪除重複項,而不僅僅是統一組合列表。 – 2012-07-26 06:32:18

+0

合併對他來說沒問題 - 但我沒注意,如果對象只有相同的ID,對象就是「重複的」。所以地圖是一個更好的方法 – 2012-07-26 06:34:43

+0

感謝安德烈亞斯,其工作良好.... – John 2014-08-14 12:46:38

1

如果你的類有一個正確實施equalshashCode方法,把列表爲HashSet,以消除重複。構造函數HashSet<T>接受Collection<T>,所以你應該很好走。

如果您需要一些自定義比較器功能(如您的案例中只比較id),請在創建TreeSet時自定義Comparator<T>實施。綜上所述,只需創建一個比較器,比較兩個對象的id s並將其傳遞給TreeSet構造函數。然後將這兩個列表中的項目添加到該集合中將會消除重複項。例如:

public class Test { 

    public static void main(String[] args) { 
     Person p1 = new Person("first", "id1"); 
     Person p2 = new Person("dummy", "id1"); // same id as above 
     Person p3 = new Person("second", "id2"); 
     Person p4 = new Person("third", "id1"); 
     List<Person> asList = Arrays.asList(p1, p2, p3, p4); 
     CustomComparator comparator = new CustomComparator(); 
     TreeSet<Person> ts = new TreeSet<Person>(comparator); 
     TreeSet<Person> duplicates = new TreeSet<Person>(comparator); 
     for (Person p : asList) { 
      if (ts.contains(p) || duplicates.contains(p)) { 
       duplicates.add(p); 
       ts.remove(p); 
      } else { 
       ts.add(p); 
      } 
     } 
     System.out.println(ts); 
    } 

} 

class Person { 

    public Person(String name, String id) { 
     super(); 
     this.name = name; 
     this.id = id; 
    } 

    public String name; 

    public String id; 

    @Override 
    public String toString() { 
     StringBuilder builder = new StringBuilder(); 
     builder.append("Person [id="); 
     builder.append(id); 
     builder.append(", name="); 
     builder.append(name); 
     builder.append("]"); 
     return builder.toString(); 
    } 

} 

class CustomComparator implements Comparator<Person> { 

    @Override 
    public int compare(Person o1, Person o2) { 
     return o1.id.compareTo(o2.id); 
    } 

} 
+0

其實我已經重寫equals()刪除基於字段fName的重複項(即使用removeAll從一個列表中刪除共同的fName )...但在「id」字段的情況下,我想從兩個列表中刪除。所以不知道我該如何實現這個目標? – testndtv 2012-07-26 06:27:18

+0

我已經添加了一個示例片段用於說明目的。 – 2012-07-26 06:31:30

+0

我剛剛試過了你給的例子......它刪除了一個重複的對象......我想刪除這兩個重複的對象......即,根據你的例子,最後,它應該只返回1條記錄(id2)... – testndtv 2012-07-26 06:38:49

0

爲此目的使用Set

注意:如果將可變對象用作設置元素,必須非常小心。如果對象的值以影響等於比較的方式更改,而對象是集合中的元素,則不會指定集的行爲。這種禁止的一個特例是,一個集合不允許自己包含一個元素。

0
HashSet<Integer> list_1_ids = new HashSet<Integer>(); 
HashSet<Integer> list_2_ids = new HashSet<Integer>(); 
for (CustomObject x : list1) list_1_ids.add(x.id); 
for (CustomObject x : list2) list_2_ids.add(x.id); 
HashSet<Integer> both_ids = list_1_ids; 
both_ids.retainAll(list_2_ids); 
List<CustomObject> pruned_list_1 = new ArrayList<CustomObject>(); 
for (CustomObject x : list1) if (!both_ids.contains(x.id)) pruned_list_1.add(x); 
List<CustomObject> pruned_list_2 = new ArrayList<CustomObject>(); 
for (CustomObject x : list2) if (!both_ids.contains(x.id)) pruned_list_2.add(x);