在之前的项目中,有同事就用过lambda表达式。之前只是泛泛的用了一下,今天找了一本书实际的看了一下《精通lambda表达式 java多核编程》。
下载链接:
链接: https://pan.baidu.com/s/1mNncEt5fj6cL0h7YXpyY0A 提取码: cjlj
下面是看书笔记。
首先准备一个实体类,用于写demo程序
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Name{
private String name;
public Integer age;
Name(){
}
Name(Integer age){
this.age = age;
}
Name(String name){
this.name = name;
}
}
书中首先提到了,lambda表达式与匿名内部类具有相似性
private List<Name> names = new ArrayList<>();
int n = 10;
for (int i = 0; i < n; i++) {
Name name = new Name();
name.setName(i+"");
names.add(name);
}
names.forEach(new Consumer<Name>() {
@Override
public void accept(Name s) {
log.info("{}", s.getName());
}
});
这段程序采用匿名内部类的方式,实现了对names中所有成员的name元素的打印。这种匿名内部类的写法在日常工程项目中是非常常见的。比如 实现数据库事务、对象比较接口等的时候。
在有了lambda表达式之后,可以简化为
names.forEach(s -> {
log.info("{}",s.getName());
});
其中,lambda表达式会猜测出里面的表达式中参数的类型,如果lambda表达式无法通过上线文对参数类型进行猜测的话,需要程序员显示的标识参数的类型。就像下面这样
names.forEach((Name s) -> {
log.info("{}",s.getName());
});
然后来看看下面的例子
List<Name> names1 = new ArrayList<>();
int n = 10000;
for (int i=0;i<n;i++){
names1.add(new Name(i+1));
}
Integer ageSum1 = names1.stream()
.map(name -> new Name(name.age*2+1))
.mapToInt(name-> name.getAge())
.sum();
lambda表达式可以和流运算结合起来实现多核并行编程,在小编以前的所有项目中,都只利用了计算机的一个核。这里是简单的一个流运算的例子,首先通过 list调用stream()方法,将数据转化成一个 Stream<Name>的结构,然后通过Map对整个流做操作。还记得大数据课上做过的实验(Map-reduce),这里的Map不是指的数据结构Map,它表示一种动作,表示对流中所有元素进行括号内处理并整合,由于流中各个成员是相互独立的,所以就可以利用多核来提高处理效率。Stream<Object> 提供了对元素的很多操作的方法,有需要了解的同学可以看看上面的书,或者自己写一段代码来试试。
其实,多核的流一般是调用另一个方法 p a r a l l e l S t r e a m ( ) parallelStream() parallelStream()
List<Name> names1 = new ArrayList<>();
int n = 10000;
for (int i=0;i<n;i++){
names1.add(new Name(i+1));
}
Integer ageSum = names1.parallelStream()
.map(name -> new Name(name.age*2+1))
.mapToInt(name-> name.getAge())
.sum();
从名字就可以看出,parallel 的中文意思就是平行。但是如果你测试上面两份代码的运行时间可能会发现 第一个的消耗时间可能比第二个少一些。这主要与你系统环境以及jvm的运行情况有关,但是从线上时间段统计观察,并行流的速度肯定高于单核流的。