Java中的小知識——lambda表達式

從匿名內部類引入Lambda表達式

線程池那篇博客中,我們通過使用匿名內部類來作爲參數傳入submit方法中。
在這裏插入圖片描述
但是我們發現,這樣雖然在步驟上簡單了許多,但是在空間上看着並不簡單,甚至顯得比較複雜。

那我們就用更簡單的lambda表達式來代替匿名內部類。

package executors;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Demo2 {
	public static void main(String[] args) {
		ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(5);
		
		newFixedThreadPool.submit(new Runnable() {
			
			@Override
			public void run() {
				System.out.println("未自定義runnable接口實現類"+Thread.currentThread().getName());
				
			}
		});
		
		
		
		newFixedThreadPool.submit(() ->  
		{
			System.out.println("未自定義runnable接口實現類"+Thread.currentThread().getName());
		});
		
		newFixedThreadPool.submit(()->System.out.println("未自定義runnable接口實現類"+Thread.currentThread().getName()));
		newFixedThreadPool.submit(()->System.out.println("未自定義runnable接口實現類"+Thread.currentThread().getName()));
		newFixedThreadPool.submit(()->System.out.println("未自定義runnable接口實現類"+Thread.currentThread().getName()));
		
	}
}


在這裏插入圖片描述

Lambda表達式

思想 "說重點"
lambda表達式的核心即在於說重點
以線程代碼爲例,他需要的是什麼?最核心的東西是什麼?
就是run方法!!!
runnable接口中重寫實現的就一個run方法!!!接口只是run方法的載體,裝黃桃的罐頭盒子!!!核心只要run方法。
我們爲什麼要寫runnable接口的實現類?就是爲了重寫run方法,並且讓線程去執行run方法。
所以,現在我們不要盒子了,直接用手抓着吃!!!

service.submit(new Runnable() {                                          
	@Override                                                
	public void run() {                                      
		System.out.println(Thread.currentThread().getName());
	}                                                        
});                                                          

/*
匿名內部類方式來作爲線程池執行目標代碼
	1. 這個方法需要的參數是Runnable接口的實現類對象
	2. Runnable接口目標是爲了提供一個run 方法, What will be run
	3. What will be run??? where??? run方法內容
	
這裏需要Runnable提供Run方法,提供Run方法方法體

"說重點"
	需要Run方法方法體
*/  

Lambda表達式格式

service.submit(() -> System.out.println(Thread.currentThread().getName()));

() -> System.out.println(Thread.currentThread().getName())
Lambda表達式

() 參數列表
-> 做什麼事情,就是對應方法體
箭頭之後的代碼就是正常語句

(參數列表) -> {代碼語句}

Lambda表達式使用,無參數無返回值

package com.qfedu.c_lambda;

/*
 * 無參數無返回值
 */

interface Cook {
	void cooking();
}

public class Demo1 {
	public static void main(String[] args) {
		invokeCook(new Cook() {
			
			@Override
			public void cooking() {
				System.out.println("麻辣香鍋,孜然肉片,土豆牛肉,蒜薹肉絲");
			}
		});
		
		invokeCook(() -> {
			System.out.println("蒜蓉油麥菜,番茄雞蛋");
		});
		
		invokeCook(() -> System.out.println("明天早上自己炸油條"));
	}
	
	/**
	 * 執行Cook實現類對象方法
	 * 
	 * @param cook Cook接口的實現類對象
	 */
	public static void invokeCook(Cook cook) {
		cook.cooking();
	}
}

Lambda表達式使用,有參數有返回值

這裏面用到了Arrays.sort方法
後邊是comparator接口 比較器實現
在這裏插入圖片描述

package com.qfedu.c_lambda;

import java.util.Arrays;
import java.util.Comparator;

public class Demo2 {
	public static void main(String[] args) {
		Person[] persons = {
				new Person("騷磊", 16),
				new Person("老黑", 50),
				new Person("老付", 40),
				new Person("污雲", 35),
				new Person("朋朋", 14),
				new Person("大哥", 18),
		};
		
		// public static <T> void sort(T[] a, Comparator<? super T> c)
		Arrays.sort(persons, new Comparator<Person>() {

			@Override
			public int compare(Person o1, Person o2) {
				return o1.getAge() - o2.getAge();
			}
		});
		
		/*
		 * 1. 有參數
		 * 2. 有返回值
		 * 
		 * (Person o1, Person o2) -> {
		 * 		return o1.getAge() - o2.getAge();
		 * }
		 * 標準Lambda
		 */
		Arrays.sort(persons, (Person o1, Person o2) -> {
			return o2.getAge() - o1.getAge();
		});
		
		/*
		 * 1. 這裏可以省略數據類型
		 * 2. 可以直接利用返回值,{}和return都省了掉
		 */
		Arrays.sort(persons, (o1, o2) -> o2.getAge() - o1.getAge());
		
		for (Person person : persons) {
			System.out.println(person);
		}
	}
}

甚至還可以更加簡化,省略數據類型,但最好不要

package com.qfedu.c_lambda;

interface A {
	float add(int num1, float num2);
}

public class Demo3 {
	public static void main(String[] args) {
		System.out.println(new A() {
			
			@Override
			public float add(int num1, float num2) {
				return num1 + num2;
			}
		}.add(5, 13.5F));
		
		/*
		 * 1. 數據類型真的可以省略,雖然是不同數據類型,Java語言真香
		 * 2. 實現的代碼非一行,可以在大括號內完成你的目標
		 */
		test(5, 13.5F, (num1, num2) -> {
			float sum = num1 + num2;
			return sum;
		});	
	}
	
	public static void test(int num1, float num2, A a) {
		System.out.println(a.add(num1, num2));
	}
}

Lambda表達式使用前提

  1. 有且只有一個缺省屬性爲public abstract方法的接口,例如 Comparator接口,Runnable接口

  2. 使用lambda表達式是有一個前後要求約束的方法的參數爲接口類型,或者說局部變量使用調用方法,可以使用lambda也OK

  3. 有且只有一個抽象方法的接口,稱之爲【函數式接口】Comparator接口,Runnable接口

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章