HashSet的随机开始索引迭代器

时间:2011-01-07 15:35:18

标签: java data-structures

我对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的原因是它会产生不必要的开销。根据我的研究,我无法找到一种用起始索引创建迭代器的实用方法。

所以,我的问题是,在最小化开销的同时实现目标的好方法是什么?

谢谢。

5 个答案:

答案 0 :(得分:5)

add()remove()HashSet中速度快的原因。您正在交易能够将集合中的元素视为速度和内存成本的随机访问列表。

我担心你不能真的这样做,除非你先把你的Set转换成List。这很简单,但它通常涉及对集合中所有元素的完整处理。如果你想要从某个地方多次启动迭代器的能力形成相同的状态,那么它可能是有意义的。如果没有,那么你现在的方法可能会更好。

现在代码(假设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 :(得分:2)

HashSet没有订单。所以你可以把这个集合放到一个可以使用索引的List中。

示例:

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

答案 2 :(得分:2)

由于HashSet的迭代器没有特定的顺序生成项目,所以从开头或结尾丢弃100个项目并没有什么区别。

从最后删除项目会更快。

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

答案 3 :(得分:1)

您可以使用NavigableMap。如果您可以依赖键(并从某个键开始),那就是开箱即用。

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

然后你将使用生成的子图来简单地获取iterator()并完成你的工作。 否则,如果必须从某个索引处开始,则可能需要使用临时列表。

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

然后按上述方式获取子图。

答案 4 :(得分:0)

按照@ toader的建议。

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

注意:第n个值对HashSet没有意义。也许你需要一个SortedSet,在这种情况下,100th将是第100大值。