[英]What is the fastest way to find orphans between two large (size ~900K ) Vectors of Strings in Java?
我目前正在處理處理大量數據所需的Java程序。 我有兩個向量...
Vector collectionA = new Vector();
Vector collectionB = new Vector();
...並且在處理過程中,它們都將包含約900,000個元素。
我需要找到collectionB中所有未包含在collectionA中的項目。 現在,這就是我的操作方式:
for (int i=0;i<collectionA.size();i++) {
if(!collectionB.contains(collectionA.elementAt(i))){
// do stuff if orphan is found
}
}
但是,這會使程序運行很多小時,這是不可接受的。
有什么方法可以調整此時間,以便我可以大大減少運行時間?
我想我讀過一次,使用ArrayList而不是Vector更快。 使用ArrayLists而不是Vectors可以解決此問題嗎?
使用HashSet進行查找。
說明:
當前,您的程序必須測試collectionB中的每個項目,以查看它是否等於當前正在處理的collectionA中的項目( contains()
方法將需要檢查每個項目)。
你應該做:
Set<String> set = new HashSet<String>(collectionB);
for (Iterator i = collectionA.iterator(); i.hasNext(); ) {
if (!set.contains(i.next())) {
// handle
}
}
使用HashSet將有所幫助,因為該集將為每個元素計算一個哈希並將該元素存儲在與一系列哈希值關聯的存儲桶中。 在檢查某個項目是否在集合中時,該項目的哈希值將直接標識該項目應位於的存儲桶。現在只需要檢查該存儲桶中的項目。
使用類似TreeSet
的SortedSet
也會比Vector
有所改進,因為要找到該項目,僅要檢查其所在的位置,而不是所有位置。 哪種Set
實現效果最佳取決於數據。
如果元素的順序無關緊要,則可以使用HashSets ,並按以下步驟進行:
Set<String> a = new HashSet<>();
Set<String> b = new HashSet<>();
// ...
b.removeAll(a):
因此,在本質上,你從集中刪除b
凡在集合中的元素a
,留下的不對稱差集 。 請注意, removeAll
方法確實會修改集合b
,因此,如果這不是您想要的,則需要首先創建一個副本。
要了解是否HashSet
或TreeSet
是這種類型的操作更有效率,我跑到下面的代碼與這兩種類型,並用番石榴的Stopwatch
來測量執行時間。
@Test
public void perf() {
Set<String> setA = new HashSet<>();
Set<String> setB = new HashSet<>();
for (int i=0; i < 900000; i++) {
String uuidA = UUID.randomUUID().toString();
String uuidB = UUID.randomUUID().toString();
setA.add(uuidA);
setB.add(uuidB);
}
Stopwatch stopwatch = Stopwatch.createStarted();
setB.removeAll(setA);
System.out.println(stopwatch.elapsed(TimeUnit.MILLISECONDS));
}
在我使用Oracle JDK 7的普通開發機器上, TreeSet
變體(〜450ms)比HashSet
變體(〜105ms)慢大約4倍。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.