不明白Java为什么要引入Lambda表达式。只有在很少的情况下用它来替换匿名类可能会少那么三、四行代码,可是,我们成千上万的代码都写了,谁会在乎这么一点呢?并且,Lambda表达式限制条件比匿名类多,匿名类它是类,类是面向对象语言的核心,它比Lambda表达式功能强多了。
Lambda与性能也没有什么关系。想提高性能要优化算法、充分利用计算资源,与Lambda表达式有什么关系呢?
还有说引入面向函数式编程思想,这个也没看出来。
首先做个测试。用随机数填充集合,然后遍历集合,取出能被2整除的数字并保存在中间结果中,再从中间结果取出最大的数。分别用了迭代器、外循环、内循环、集合普通流、集合并行流、自定义多线程,结果如下:
使用lambda表达式后,代码没变少、没更可读、性能也没更高。最后一种方式因为要自己处理多线程问题,代码量变多。但自已实现的话好像更加灵活。
第一种迭代器:
package com.xxxxxx.test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
public class Lambda0 {
private ArrayList srcArray = new ArrayList();
public static void main(String[] args) {
// 初始化srcArray数组
Lambda0 lam0 = new Lambda0();
Random rand = new Random();
for (int i = 0; i < 100000; i++) {
lam0.srcArray.add(rand.nextInt(100000));
}
// 开始计时
long start = System.currentTimeMillis();
// midArray用来保存中间结果
ArrayList midArray = new ArrayList();
Iterator iter = lam0.srcArray.iterator();
// 使用迭代器
while (iter.hasNext()) {
// 这个循环用来消耗时间
for (int l = 0; l < 1000000; l++) {
if ((l % 2) == 0) {
l = l * 2;
l = l / 2;
}
}
// 将srcArray中能被2整除的数放在midArray数组中
Integer value = iter.next();
if ((value % 2) == 0) {
midArray.add(value);
}
}
// 从midArray中找出最大的整数
class Max {
public int value = 0;
}
Max max = new Max();
// 使用迭代器
iter = midArray.iterator();
while (iter.hasNext()) {
Integer value = iter.next();
if (value > max.value) {
max.value = value;
}
}
// 计时结束
long end = System.currentTimeMillis();
// 输出结果
System.out.println("[Max]" + max.value + ",[time]" + (end - start));
}
}
第二种外循环:
package com.xxxxxx.test;
import java.util.ArrayList;
import java.util.Random;
public class Lambda1 {
private ArrayList srcArray = new ArrayList();
public static void main(String[] args) {
// 初始化srcArray数组
Lambda1 lam1 = new Lambda1();
Random rand = new Random();
for (int i = 0; i < 100000; i++) {
lam1.srcArray.add(rand.nextInt(100000));
}
// 开始计时
long start = System.currentTimeMillis();
// midArray用来保存中间结果
ArrayList midArray = new ArrayList();
for (Integer i : lam1.srcArray) {
// 这个循环用来消耗时间
for (int l = 0; l < 1000000; l++) {
if ((l % 2) == 0) {
l = l * 2;
l = l / 2;
}
}
// 将srcArray中能被2整除的数放在midArray数组中
if ((i % 2) == 0) {
midArray.add(i);
}
}
// 从midArray中找出最大的整数
Integer max = 0;
for (Integer i : midArray) {
if (i > max) {
max = i;
}
}
// 计时结束
long end = System.currentTimeMillis();
// 输出结果
System.out.println("[Max]" + max + ",[time]" + (end - start));
}
}
第三种内循环:
package com.xxxxxx.test;
import java.util.ArrayList;
import java.util.Random;
public class Lambda2 {
private ArrayList srcArray = new ArrayList();
public static void main(String[] args) {
// 初始化srcArray数组
Lambda2 lam2 = new Lambda2();
Random rand = new Random();
for (int i = 0; i < 100000; i++) {
lam2.srcArray.add(rand.nextInt(100000));
}
// 开始计时
long start = System.currentTimeMillis();
// midArray用来保存中间结果
ArrayList midArray = new ArrayList();
lam2.srcArray.forEach((i) -> {
// 这个循环用来消耗时间
for (int l = 0; l < 1000000; l++) {
if ((l % 2) == 0) {
l = l * 2;
l = l / 2;
}
}
// 将srcArray中能被2整除的数放在midArray数组中
if ((i % 2) == 0) {
midArray.add(i);
}
});
// 从midArray中找出最大的整数
class Max {
public int value = 0;
}
Max max = new Max();
// 直接使用Integer max = 0不行
midArray.forEach((i) -> {
if (i > max.value) {
max.value = i;
}
});
// 计时结束
long end = System.currentTimeMillis();
// 输出结果
System.out.println("[Max]" + max.value + ",[time]" + (end - start));
}
}
第四种集合stream:
package com.xxxxxx.test;
import java.util.ArrayList;
import java.util.Random;
public class Lambda3 {
private ArrayList srcArray = new ArrayList();
public static void main(String[] args) {
// 初始化srcArray数组
Lambda3 lam3 = new Lambda3();
Random rand = new Random();
for (int i = 0; i < 100000; i++) {
lam3.srcArray.add(rand.nextInt(100000));
}
// 开始计时
long start = System.currentTimeMillis();
// midArray用来保存中间结果,流处理不需要
// ArrayList midArray = new ArrayList();
class Max {
public int value = 0;
}
Max max = new Max();
// 普通流
lam3.srcArray.stream().filter((i) -> {
// 这个循环用来消耗时间
for (int l = 0; l < 1000000; l++) {
if ((l % 2) == 0) {
l = l * 2;
l = l / 2;
}
}
if ((i % 2) == 0) {
return true;
} else {
return false;
}
}).forEach((i) -> {
// 从流中找出最大的整数
if (i > max.value) {
max.value = i;
}
});
// 计时结束
long end = System.currentTimeMillis();
// 输出结果
System.out.println("[Max]" + max.value + ",[time]" + (end - start));
}
}
第五种集合并行stream:
package com.xxxxxx.test;
import java.util.ArrayList;
import java.util.Random;
public class Lambda4 {
private ArrayList srcArray = new ArrayList();
public static void main(String[] args) {
// 初始化srcArray数组
Lambda4 lam4 = new Lambda4();
Random rand = new Random();
for (int i = 0; i < 100000; i++) {
lam4.srcArray.add(rand.nextInt(100000));
}
// 开始计时
long start = System.currentTimeMillis();
// midArray用来保存中间结果,流处理不需要
// ArrayList midArray = new ArrayList();
class Max {
public int value = 0;
}
Max max = new Max();
// 并发流
lam4.srcArray.parallelStream().filter((i) -> {
// 这个循环用来消耗时间
for (int l = 0; l < 1000000; l++) {
if ((l % 2) == 0) {
l = l * 2;
l = l / 2;
}
}
if ((i % 2) == 0) {
return true;
} else {
return false;
}
}).forEach((i) -> {
// 从流中找出最大的整数
if (i > max.value) {
max.value = i;
}
});
// 计时结束
long end = System.currentTimeMillis();
// 输出结果
System.out.println("[Max]" + max.value + ",[time]" + (end - start));
}
}
第六种自定义多线程:
package com.xxxxxx.test;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
public class Lambda5 {
private ArrayList srcArray = new ArrayList();
public static void main(String[] args) {
// 初始化srcArray数组
Lambda5 lam5 = new Lambda5();
Random rand = new Random();
for (int i = 0; i < 100000; i++) {
lam5.srcArray.add(rand.nextInt(100000));
}
// 取得CPU核数,本机是4核
int nThreads = Runtime.getRuntime().availableProcessors();
// 用于等待多线和结束
final CountDownLatch threadsCount = new CountDownLatch(nThreads);
// 实现Runnable的内部类
class MyRunnable implements Runnable {
int start = 0;
int end = 0;
Integer max = 0;
MyRunnable(int start, int end) {
this.start = start;
this.end = end;
}
public void run() {
// midArray用来保存中间结果
ArrayList midArray = new ArrayList();
ArrayList tempArray = new ArrayList(lam5.srcArray.subList(start, end));
for(Integer i : tempArray) {
// 这个循环用来消耗时间
for (int l = 0; l < 1000000; l++) {
if ((l % 2) == 0) {
l = l * 2;
l = l / 2;
}
}
if ((i % 2) == 0) {
midArray.add(i);
}
}
for (Integer i : midArray) {
if (i > max) {
max = i;
}
}
threadsCount.countDown();
}
}
// 开始计时
long start = System.currentTimeMillis();
// 有可能出现小数,因此加1补足
int step = lam5.srcArray.size() / nThreads + 1;
// 保存线程对象
ArrayList threadsArrayList = new ArrayList();
for(int i = 0; i < nThreads; i ++) {
int startIndex = i * step;
int endIndex = (i + 1) * step < lam5.srcArray.size() ? (i + 1) * step : lam5.srcArray.size();
MyRunnable temp = new MyRunnable(startIndex, endIndex);
threadsArrayList.add(temp);
new Thread(temp).start();
}
// 等待所有线和结束
try {
threadsCount.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 找出最大整数
int max = 0;
for (MyRunnable i : threadsArrayList) {
if (i.max > max) {
max = i.max;
}
}
// 计时结束
long end = System.currentTimeMillis();
// 输出结果
System.out.println("[Max]" + max + ",[time]" + (end - start));
}
}