结论,效率:java8的foreach > 增强for > 普通for循环
如果你不信,请往下看。
今天在一个技术群中看到了一下讨论,有同学说“慎用java8的foreach循环”,并且给出了很多博客的截图和链接,其中有一位博主的博客测试方法写了很多。
链接如下:http://www.cnblogs.com/yiwangzhibujian/p/6919435.html
他最后的结论:http://www.cnblogs.com/yiwangzhibujian/p/6965114.html
的确,如果你在百度上搜索java for foreach java8 等关键词会出现很多的搜索结果,比如这几个循环效率的对比。并且很多博主的结论是java8的foreach循环是真的菜,效率不是差的一点点!!!慎用,之类的。
我的思考:若java8的foreach效率如此低下,为何还要推出?难道jdk的开发人员不会优化一下?
带着这个思考,我仔细看了“已往之不谏”的博主最后为java8 正名的博客,写的不错,测试也很充分(说实话,没有仔细的阅读)但是结论很明显。java8胜了。作者为了证明java8不是吃素的,确实下了不少功夫。
最后的最后,作者提到了,
java8的foreach预热是jvm级别的,需要预热。
针对这一点,我想是不是能对作者的第一篇博客的测试方式进行一下改进?
那我们就给jvm预热一下,下面是我的测试。
package cn.edu.zua.corejava.java8.foreach;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
* ForiForeachJava8ForeachTest
*
* @author ascend
* @date 2018/6/22 15:28.
*/
public class ForiForeachJava8ForeachTest {
public static void main(String[] args) {
// 预热
List<Dog> tmpList = listDog(10);
testFori(tmpList);
testForeach(tmpList);
testJava8ForEach(tmpList);
List<Integer> list = Arrays.asList(10, 50, 250, 1000, 2000, 3000, 5000, 10000, 20000);
for (int i = 0; i < list.size(); i++) {
test(list.get(i));
}
}
public static void test(int size) {
System.out.println("-----------次数:" + size + "------------");
List<Dog> list = listDog(size);
long nanoTime = System.nanoTime();
testFori(list);
long nanoTime1 = System.nanoTime();
testForeach(list);
long nanoTime2 = System.nanoTime();
testJava8ForEach(list);
long nanoTime3 = System.nanoTime();
System.out.println("fori\t\t\t\t" + (int) (nanoTime1 - nanoTime) / 1000.0 + " ms");
System.out.println("增强for\t\t\t\t" + (int) (nanoTime2 - nanoTime1) / 1000.0 + " ms");
System.out.println("java8 foreach\t\t" + (int) (nanoTime3 - nanoTime2) / 1000.0 + " ms");
System.out.println();
}
/**
* 初始化list
*
* @param size int
* @return list
*/
public static List<Dog> listDog(int size) {
List<Dog> list = new ArrayList<>();
for (int i = 0; i < size; i++) {
list.add(new Dog(i + 1, "dog " + (i + 1)));
}
return list;
}
/**
* 测试fori
*
* @param list List
*/
public static void testFori(List<Dog> list) {
for (int i = 0; i < list.size(); i++) {
list.get(i).hashCode();
}
}
/**
* 测试增强for循环
*
* @param list List
*/
public static void testForeach(List<Dog> list) {
for (Dog dog : list) {
dog.hashCode();
}
}
/**
* 测试java8的foreach
*
* @param list List
*/
public static void testJava8ForEach(List<Dog> list) {
list.forEach(dog -> dog.hashCode());
}
}
/**
* 测试实体类,用来计算hashCode
*/
class Dog {
private int age;
private String name;
public Dog(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
int result = 17;
result = 31 * result + age;
result = 31 * result + (name == null ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof Dog)) {
return false;
}
Dog dog = (Dog) obj;
return dog.age == this.age &&
Objects.equals(dog.name, this.name);
}
}
笔者运行的几组数据
笔者根据数据1,绘图如下:
大家也可以多多进行测试。
笔者机器配置:
看这里,看这里
文章总目录:博客导航
参考文章:https://blog.csdn.net/u_ascend/article/details/80777033