前面讲list转树形结构的时候,由于业务原因无法使用最快的方法,导致很慢,今天就研究在循环上提升速度。
Java8 lambda遍历出来后有人说它快有人说它要慎用?到底怎么回事让我们来一探究竟吧!看不懂可以先看后面的分析
测试代码:
package cn.cncommdata.zhonglvreport;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
public class ForiForeachJava8ForeachTest {public static void main(String[] args) {
// 预热
List tmpList = listDog(10);
long time1 = System.nanoTime();
testFori(tmpList);
long time2 = System.nanoTime();
testForeach(tmpList);
long time3 = System.nanoTime();
testJava8ForEach(tmpList);
long time4 = System.nanoTime();
System.out.println("for2\t\t\t\t" + (int) (time2 - time1) / 1000.0 + " ms");
System.out.println("增强for\t\t\t\t" + (int) (time3 - time2) / 1000.0 + " ms");
System.out.println("java8 foreach\t\t" + (int) (time4 - time3) / 1000.0 + " ms");
List 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 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();
testJava8ForEachStream(list);
long nanoTime4 = 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("java8 Stream foreach\t\t" + (int) (nanoTime4 - nanoTime3) / 1000.0 + " ms");
System.out.println();
}/**
* 初始化list
*
* @param size int
* @return list
*/
public static List listDog(int size) {
List 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 list) {
for (int i = 0;
i < list.size();
i++) {
list.get(i).hashCode();
}
}/**
* 测试增强for循环
*
* @param list List
*/
public static void testForeach(List list) {
for (Dog dog : list) {
dog.hashCode();
}
}/**
* 测试java8的foreach
*
* @param list List
*/
public static void testJava8ForEach(List list) {
list.forEach(dog -> dog.hashCode());
}/**
* 测试java8的foreach
*
* @param list List
*/
public static void testJava8ForEachStream(List list) {
list.stream().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);
}
}
运行结果:
-------不预热的情况下-------
for213.5 ms
增强for162.5 ms
java8 foreach41539.1 ms
java8 Stream foreach 2365.4 ms
-----------预热情况次数:10------------
fori3.6 ms
增强for4.7 ms
java8 foreach3.8 ms
java8 Stream foreach 6.9 ms-----------预热情况次数:50------------
fori9.7 ms
增强for13.1 ms
java8 foreach8.6 ms
java8 Stream foreach 11.1 ms-----------预热情况次数:250------------
fori50.6 ms
增强for63.4 ms
java8 foreach32.1 ms
java8 Stream foreach 34.5 ms-----------预热情况次数:1000------------
fori205.9 ms
增强for255.9 ms
java8 foreach101.9 ms
java8 Stream foreach 74.7 ms-----------预热情况次数:2000------------
fori142.1 ms
增强for322.8 ms
java8 foreach164.5 ms
java8 Stream foreach 153.5 ms-----------预热情况次数:3000------------
fori193.9 ms
增强for167.5 ms
java8 foreach136.8 ms
java8 Stream foreach 118.0 ms-----------预热情况次数:5000------------
fori154.1 ms
增强for125.2 ms
java8 foreach98.7 ms
java8 Stream foreach 73.8 ms-----------预热情况次数:10000------------
fori263.6 ms
增强for196.3 ms
java8 foreach131.5 ms
java8 Stream foreach 163.1 ms-----------预热情况次数:20000------------
fori417.3 ms
增强for411.6 ms
java8 foreach593.4 ms
java8 Stream foreach 476.9 ms
【java8新特性|java 8 lambda遍历和增强for循环的效率哪个快()】分析:我这里测试用了4种for循环
从第一个结果来看在jvm不预热的情况下lambda遍历方式反而花费的时间更长(jvm预热可以单独去查看是什么意思)
从后面的结果来看在jvm预热的情况下,并且数据量大的情况下lambda遍历方式花费的时间少一些,我这里没用使用Stream接口里面的方法,所以foreach比Stream().forEach快一些
推荐阅读
- java8|Java8 Lambda 新人必知(一)
- Java 将PDF转为PDF/A
- Java包装类
- Java抽象类
- 程序人生|写了这么久Java项目,是否还记得你的第一行Java代码
- j2ee好蓝|我与Java的日常记录(祝java27岁生日快乐呀)
- Java基础项目|基于Eclipse+GUI+Swing开发得俄罗斯方块项目设计和实现
- 程序员|这么热门的互联网行业,哪些岗位最有前途(薪资高吗?)
- JavaSE系列详解|Java8新特性Stream流的概念和使用【详解】