在之前的項目中,有同事就用過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> 提供了對元素的很多操作的方法,有需要了解的同學可以看看上面的書,或者自己寫一段代碼來試試。
其實,多核的流一般是調用另一個方法
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的運行情況有關,但是從線上時間段統計觀察,並行流的速度肯定高於單核流的。