[英]Deduplication using a Java Set
我有一個對象的集合,我們稱它們為A,B,C,D ......,有些與其他對象相同。 如果A和C相等,那么我想用A的引用替換對C的每個引用。這意味着(a)對象C可以被垃圾收集,釋放內存,(b)我以后可以使用“==”比較對象代替昂貴的equals()
操作。 (這些對象很大,而equals()
操作很慢。)
我的直覺是使用java.util.Set
。 當我遇到CI時,可以很容易地看到Set
的條目是否等於C.但是如果有,則似乎沒有簡單的方法來找出該條目是什么,並替換我對現有條目的引用。 我錯了嗎? 迭代所有條目以找到匹配的條目顯然是非首發。
目前,我使用Map
而不是Set
,其中值始終與鍵相同。 調用map.get(C)
然后找到A.這有效,但感覺非常令人費解。 有更優雅的方式嗎?
這個問題不是簡單的重復數據刪除:它是規范化的一種形式。
標准方法是使用Map
而不是Set
。 這是一個如何做到的草圖:
public <T> List<T> canonicalizeList(List<T> input) {
HashMap<T, T> map = new HashMap<>();
List<T> output = new ArrayList<>();
for (T element: input) {
T canonical = map.get(element);
if (canonical == null) {
element = canonical;
map.put(canonical, canonical);
}
output.add(canonical);
}
return output;
}
注意,這是O(N)
。 如果您可以安全地假設input
中重復項的百分比可能很小,那么您可以將map
和output
的容量設置為input
的大小。
現在你似乎在說你已經這樣做了(最后一段),你問的是否有更好的方法。 據我所知,沒有一個。 ( HashSet
API允許你測試一個集合是否包含一個等於element
的值,但它不會讓你知道它在O(1)
是什么。)
值得一提的是, HashSet<T>
類實現為HashMap<T, T>
。 所以你不會直接使用HashSet
節省時間或空間......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.