性能:从HashMap.values()创建一个ArrayList

时间:2010-11-23 10:30:14

标签: java performance collections arraylist hashmap

问题是从HashMap.values()集合创建ArrayList的成本是多少?或者单独创建值Collection? 假设Map.size()> 100K。 对象也可以一直保存在ArrayList(而不是HashMap)中,这对其他部分有影响(元素的修改,易于按键)。 ArrayList用于迭代每个第n个元素。 (这就是为什么不能直接使用值集合的原因)。在迭代期间不进行任何修改。

5 个答案:

答案 0 :(得分:39)

HashMap.values()不会返回ArrayList个值,而是Values个集合。

来源:

 public Collection<V> values() {
        Collection<V> vs = values;
        return (vs != null ? vs : (values = new Values()));
    }

ValuesAbstractCollection。值的原因只是引用HashMap的迭代器。

你的问题:

  

问题是它的成本是多少   从a创建一个ArrayList   HashMap.values()Collection?

这是线性的复杂性(如Bozho所说),因为

ArrayList<V> valuesList = new ArrayList<V>(hashMap.values());

ArrayList,valuesList调用集合hashMap toArray()方法,该方法基本上从集合中的0..N(大小)元素执行for循环。

希望这有帮助。

答案 1 :(得分:8)

HashMap在内部将值存储在集合values中。请查看AbstractMap的父HashMap的{​​{3}}。

因此HashMap.values()会直接返回Collection。没有完成计算或数据复制。它尽可能快。

只需获取值,然后执行for循环:

int n = 5;  // every 5th element
Object[] values = hashMap.values().toArray();
int size = values.length;
for (int i = 0; i < size; i += n){
   values[i];
   // do something
)

答案 2 :(得分:3)

要详细说明@ Bozho的解决方案,你可以这样做。

int count = 0;
for(Value value: map.values())
   if(count++ % 5 == 0)
     // do something.

答案 3 :(得分:2)

您可以使用Iterator跳过元素 - 只需多次调用next()

创建任何集合的列表具有线性复杂性。

答案 4 :(得分:0)

您可以创建自己的HashMap,它直接保存Arraylist值集合(我不相信HashMap是免费的,它的数据结构是不同的)。但这需要你方的一些额外编码。