2009-11-03 161 views
13

簡單的問題。比較兩個列表的更新,刪除和添加

我有一個新的列表和一箇舊的列表。在Java中,是否有一個標準的方法/庫允許我比較這兩個列表並確定哪些項目已被更新/刪除或是全新的?例如。我最終應該列出三個清單 - 刪除的項目(舊的項目但不是新的項目),更新的項目(兩個項目),新的項目(新的項目而不是舊的項目)。

我可以自己寫這個,但想知道是否有一個標準的方法來做到這一點。

列表中的對象實現等於正確。

+0

您是否在意列表順序?例如,迄今爲止提出的涉及retainAll/removeAll的解決方案不會處理新列表包含與舊列表相同的元素的情況,儘管順序不同;例如{「foo」,「bar」} vs {「bar」,「foo」}。 – Adamski 2009-11-03 14:53:50

+0

只要equals方法實現correclty,我不明白爲什麼順序應該影響removeAll等。當然不會在javadoc中提示:從此列表中刪除指定集合(可選操作)中包含的所有元素。 – Pablojim 2009-11-04 13:12:22

回答

31

沒有標準對不起。但是,使用標準JDK可以非常輕鬆地完成此任務,而無需依賴Apache Commons(如其他人所建議的那樣)。假設你的名單List<T>實例:

List<T> oldList = ... 
List<T> newList= ... 

List<T> removed = new ArrayList<T>(oldList); 
removed.removeAll(newList); 

List<T> same = new ArrayList<T>(oldList); 
same.retainAll(newList); 

List<T> added = new ArrayList<T>(newList); 
added.removeAll(oldList); 
+0

+1 - 是的,比我的好多了。 – 2009-11-03 14:25:12

+1

不幸的是,這是有點錯誤... removeAll和類似的操作傳入列表中並返回一個布爾值。所以這不會編譯。需要成爲: 列表 added = new ArrayList (newList); added.removeAll(oldList); 等... 因此,有可能是apache commons方法的情況畢竟... – Pablojim 2009-11-04 13:21:42

+0

@Pablojim:非常正確,謝謝。固定。 – cletus 2009-11-04 13:53:44

3

我會使用Apache CollectionUtils並使用聯合(在兩個項目)和析取函數(改變順序來獲得一個或另一個)。

理想情況下,你會讓所有的元素而不是3,但如果這不是瓶頸,我現在不會擔心效率。

7

標準庫中沒有任何東西。

但是Apache的共享CollectionUtils類爲您提供了交集此功能,並減去方法:

Collection<T> old = ...; 
Collection<T> neww = ...; 

Collection<T> deleted = (Collection<T>)CollectionUtils.subtract(old, new); 
Collection<T> updated = (Collection<T>)CollectionUtils.intersection(old, new); 
Collection<T> newResult = (Collection<T>)CollectionUtils.subtract(new, old); 

(你所需要的(未選中)蒙上因爲CollectionUtils沒有泛型。)

1

我想你可以用標準的Java庫做到這一點。看看java.util.Collection中的下列方法:

中的retainAll(Collection c)將

只保留此 集合,包含在 指定集合中的元素(可選 操作) 。換句話說,從該集合中刪除 所有 元素,這些元素不包含在 指定集合中。

的removeAll(Collection c)將

刪除所有該集合的元素 那些也包含在 指定集合(可選 操作)。此通話返回後, 此集合將不包含與指定的 集合共同的 元素。

0

如果有一個標準的方式,我不知道它...
我看着Collections但只看到了不相交()(這已經是一個信息......)和indexOfSubList()(不知道如果它有用的話)。
我也看了Google Collections,如果有,顯然,不是這樣的設施,那裏有一些有用的工具,如Collections2的filter()函數,這可以幫助如果你做出適當的謂語。

[編輯]我錯過了removeAll和retainAll方法的收集...我不刪除這個答案,即使有點可憐,因爲它是某種程度上與其他答案的補充...(我認爲Google Collections至少也罷!)

2

就個人而言,我認爲,唯一明智的方法來解釋二名單之間的差異是一個完全成熟的DIFF算法(類似Unix的diff命令的)。

,但是,是一個更簡單的故事。 Google Collections提供了一個Sets.difference(Set, Set)方法,以及聯合和交集。