2011-01-07 49 views
3

我使用HashSet爲add(); remove(); clear(); iterator();方法。迄今爲止,所有事情都像魅力一樣。但是,現在我需要滿足不同的要求。HashSet的隨機開始索引迭代器

我想能夠從某個索引開始迭代。例如,我希望以下兩個程序具有相同的輸出。

計劃1

Iterator it=map.iterator(); 
for(int i=0;i<100;i++) 
{ 
    it.next(); 
} 
while (it.hasNext()) 
{ 
    doSomethingWith(it.next()); 
} 

計劃2

Iterator it=map.iterator(100); 
while (it.hasNext()) 
{ 
    doSomethingWith(it.next()); 
} 

的原因,我不希望使用程序1,它創造了不必要的開銷。從我的研究中,我找不到一種用開始索引創建迭代器的實用方法。

所以,我的問題是,在最小化開銷的同時達到目標的好方法是什麼?

謝謝。

+0

你想使用什麼樣的數據結構? – Xorty 2011-01-07 15:44:41

回答

5

還有一個原因是add()remove(),速度快的HashSet。您正在交易將集合中的元素作爲隨機訪問列表來處理速度和內存成本的能力。

恐怕你不能真的那樣做,除非你先把你的Set轉換成List。這很簡單,但它通常涉及對Set中所有元素的完整處理。如果你希望能夠從某個地方不止一次地啓動迭代器,那麼它就可能是合理的。如果沒有,那麼你現在的做法可能會更好。

現在的代碼(假設Set<Integer> set = new HashSet<Integer>();是你聲明的數據結構:

List<Integer> list = new ArrayList<Integer>(set); 
list.subList(100, list.size()).iterator(); // this will get your iterator. 
1

您可以使用NavigableMap。如果你可以依靠鑰匙(並從某個鑰匙開始),那是開箱即用的。

Map<K,V> submap = navigableMap.tailMap(fromKey); 

然後,您將使用生成的子圖來簡單地獲取iterator()並完成您的工作。 否則,如果您必須從某個索引開始,則可能需要使用臨時列表。

K fromKey = new ArrayList<K>(navigableMap.keySet()).get(index); 

然後得到如上的子圖。

2

HashSet沒有順序。所以你可以把這個集合放入一個可以使用索引的列表中。

例子:

HashSet set = new HashSet(); 
//...... 
ArrayList list = new ArrayList(set); 
2

由於HashSet的迭代器產生無特定順序的項目,它並沒有真正能讓你是否刪除任何區別從一開始或結束100個項目。

從最終丟棄的物品會更快。

Iterator it = map.iterator(); 
int n = map.size() - 100; 
for (int i = 0; i < n; i++) 
    doSomethingWith(it.next()); 
0

弗洛wing @ toader的建議。

for(Integer i : new ArrayList<Integer>(set).subList(100, set.size())) { 
    // from the 100'th value. 
} 

注意:第n個值對於HashSet沒有意義。也許你需要一個SortedSet,在這種情況下,第100個將是第100個最大值。