java8 新特性之lambda表達式

Java8發佈已經有一段時間了,這次發佈的改動比較大,很多人將這次改動與Java5的升級相提並論。Java8其中一個很重要的新特性就是lambda表達式,允許我們將行為傳到函數中。想想看,在Java8

之前我們想要將行為傳入函數,僅有的選擇就是匿名內部類。Java8發佈以後,lambda表達式將大量替代匿名內部類的使用,簡化代碼的同時,更突出了原來匿名內部類中最重要的那部分包含真正邏輯的代碼。尤其是對於做數據的同學來說,當習慣使用類似scala之類的函數式編程語言以後,體會將更加深刻。現在我們就來看看Java8中lambda表達式的一些常見寫法。

1.替代匿名內部類

毫無疑問,lambda表達式用得最多的場合就是替代匿名內部類,而實現Runnable接口是匿名內部類的經典例子。lambda表達式的功能相當強大,用()->就可以代替整個匿名內部類!請看代碼:

如果使用匿名內部類:

@Test

public void oldRunable() {

new Thread(new Runnable() {

@Override

public void run() {

System.out.println("The old runable now is using!");

}

}).start();

}

而如果使用lambda表達式:

@Test

public void runable() {

new Thread(() -> System.out.println("It's a lambda function!")).start();

}

最後的輸出:

The old runable now is using!

It's a lambda function!

是不是強大到可怕?是不是簡單到可怕?是不是清晰明瞭重點突出到可怕?這就是lambda表達式的可怕之處,用極少的代碼完成了之前一個類做的事情!

2.使用lambda表達式對集合進行迭代

Java的集合類是日常開發中經常用到的,甚至說沒有哪個java代碼中沒有使用到集合類。。。而對集合類最常見的操作就是進行迭代遍歷了。請看對比:

@Test

public void iterTest() {

List<string> languages = Arrays.asList("java","scala","python");/<string>

//before java8

for(String each:languages) {

System.out.println(each);

}

//after java8

languages.forEach(x -> System.out.println(x));

languages.forEach(System.out::println);

}

如果熟悉scala的同學,肯定對forEach不陌生。它可以迭代集合中所有的對象,並且將lambda表達式帶入其中。

languages.forEach(System.out::println);

這一行看起來有點像c++裡面作用域解析的寫法,在這裡也是可以的。

3.用lambda表達式實現map

一提到函數式編程,一提到lambda表達式,怎麼能不提map。。。沒錯,java8肯定也是支持的。請看示例代碼:

@Test

public void mapTest() {

List<double> cost = Arrays.asList(10.0, 20.0,30.0);/<double>

cost.stream().map(x -> x + x*0.05).forEach(x -> System.out.println(x));

}

最後的輸出結果:

10.5

21.0

31.5

map函數可以說是函數式編程裡最重要的一個方法了。map的作用是將一個對象變換為另外一個。在我們的例子中,就是通過map方法將cost增加了0,05倍的大小然後輸出。

4.用lambda表達式實現map與reduce

既然提到了map,又怎能不提到reduce。reduce與map一樣,也是函數式編程裡最重要的幾個方法之一。。。map的作用是將一個對象變為另外一個,而reduce實現的則是將所有值合併為一個,請看:

@Test

public void mapReduceTest() {

List<double> cost = Arrays.asList(10.0, 20.0,30.0);/<double>

double allCost = cost.stream().map(x -> x+x*0.05).reduce((sum,x) -> sum + x).get();

System.out.println(allCost);

}

最終的結果為:

63.0

如果我們用for循環來做這件事情:

@Test

public void sumTest() {

List<double> cost = Arrays.asList(10.0, 20.0,30.0);/<double>

double sum = 0;

for(double each:cost) {

each += each * 0.05;

sum += each;

}

System.out.println(sum);

}

相信用map+reduce+lambda表達式的寫法高出不止一個level。

5.filter操作

filter也是我們經常使用的一個操作。在操作集合的時候,經常需要從原始的集合中過濾掉一部分元素。

@Test

public void filterTest() {

List<double> cost = Arrays.asList(10.0, 20.0,30.0,40.0);/<double>

List<double> filteredCost = cost.stream().filter(x -> x > 25.0).collect(Collectors.toList());/<double>

filteredCost.forEach(x -> System.out.println(x));

}

最後的結果:

30.0

40.0

將java寫出了python或者scala的感覺有沒有!是不是帥到爆!

6.與函數式接口Predicate配合

除了在語言層面支持函數式編程風格,Java 8也添加了一個包,叫做 java.util.function。它包含了很多類,用來支持Java的函數式編程。其中一個便是Predicate,使用 java.util.function.Predicate 函數式接口以及lambda表達式,可以向API方法添加邏輯,用更少的代碼支持更多的動態行為。Predicate接口非常適用於做過濾。

public static void filterTest(List<string> languages, Predicate<string> condition) {/<string>/<string>

languages.stream().filter(x -> condition.test(x)).forEach(x -> System.out.println(x + " "));

}

public static void main(String[] args) {

List<string> languages = Arrays.asList("Java","Python","scala","Shell","R");/<string>

System.out.println("Language starts with J: ");

filterTest(languages,x -> x.startsWith("J"));

System.out.println("\\nLanguage ends with a: ");

filterTest(languages,x -> x.endsWith("a"));

System.out.println("\\nAll languages: ");

filterTest(languages,x -> true);

System.out.println("\\nNo languages: ");

filterTest(languages,x -> false);

System.out.println("\\nLanguage length bigger three: ");

filterTest(languages,x -> x.length() > 4);

}

最後的輸出結果:

Language starts with J:

Java

Language ends with a:

Java

scala

All languages:

Java

Python

scala

Shell

R

No languages:

Language length bigger three:

Python

scala

Shell

可以看到,Stream API的過濾方法也接受一個Predicate,這意味著可以將我們定製的 filter() 方法替換成寫在裡面的內聯代碼,這也是lambda表達式的魔力!

————————————————

原文鏈接:https://blog.csdn.net/bitcarmanlee/article/details/70195403


分享到:


相關文章: