br/>testData.add(Integer.valueOf(i));
}
}
@TearDown(Level.Trial)
public void doTearDown() {
testData = new HashSet<>(500000);
}
public Set<Integer> testData = new HashSet<>(500000);
}
Java 中的 Set 也支持 Steam API 和 forEach 循环。参考之前的测试,如果我们把 Set 转换成 ArrayList,然后遍历 ArrayList,或许性能会好一些?
public List<Integer> forCStyle(BenchMarkState state){
int size = state.testData.size();
List<Integer> result = new ArrayList<>(size);
Integer[] temp = (Integer[]) state.testData.toArray(new Integer[size]);
for(int j = 0; j < size; j ++){
result.add(temp[j]);
}
return result;
}
如果把 iterator 和 C 语言形式结合起来呢?
public List<Integer> forCStyleWithIteration(BenchMarkState state){
int size = state.testData.size();
List<Integer> result = new ArrayList<>(size);
Iterator<Integer> iteration = state.testData.iterator();
for(int j = 0; j < size; j ++){
result.add(iteration.next());
}
return result;
}
或者,简单的遍历怎么样?
public List<Integer> forEach(BenchMarkState state){
List<Integer> result = new ArrayList<>(state.testData.size());
for(Integer item : state.testData) {
result.add(item);
}
return result;
}
这个主意不错,不过它的效率也不高,因为初始化一个新的 ArrayList 同样需要消耗资源。
Benchmark Mode Cnt Score Error Units
TestLoopPerformance.forCStyle avgt 200 6.013 ± 0.108 ms/op
TestLoopPerformance.forCStyleWithIteration avgt 200 4.281 ± 0.049 ms/op
TestLoopPerformance.forEach avgt 200 4.498 ± 0.026 ms/op
HashMap (使用 HashMap<E,Object> 的 HashSet) 不是为遍历所有元素设计的。遍历一个 HashMap 最快的方法是把 Iterator 和 C 语言形式结合起来,这样 JVM 就不会去调用 hasNext()。
结论
Foreach 和 Steam API 用来处理集合是很方便的。你可以更快的写代码。不过,如果你的系统很稳定,性能是一个主要的考量,你应该考虑一下重写你的循环。
欢迎学Java和大数据的朋友们加入java架构交流: 855835163
群内提供免费的架构资料还有:Java工程化、高性能及分布式、高性能、深入浅出。高架构。性能调优、Spring,MyBatis,Netty源码分析和大数据等多个知识点高级进阶干货的免费直播讲解 可以进来一起学习交流哦高效遍历Java容器
原文:http://blog.51cto.com/14158311/2351030