Day36-Lambda表達式

一、Lambda表達式簡介

什麼是Lambda?

Lambda是JAVA8添加的一個新的特性。說白了,Lambda就是一個匿名函數。

爲什麼要使用Lambda?

使用Lambda表達式可以對一個接口進行非常簡潔的實現。

Lambda對接口的要求?

要求接口中定義的必須要實現的抽象方法只能是一個。

在JAVA8中,接口加了一個新特性:default

@FunctionalInterface註解
修飾函數式接口(接口中的抽象方法只有一個)的。

二、Lambda基礎語法

Lambda是一個匿名函數
返回值 方法名 參數列表 方法體
( ) -> { }
() :用來描述參數列表
{} :用來描述方法體
-> :Lambda運算符,讀作goes to

三、Lambda語法精簡

1.參數類型

由於在接口的抽象方法中,已經定義了參數的數量和類型,所以在Lambda表達式中,參數的類型可以省略。

如果需要省略類型,則每一個參數的參數類型都要省略,千萬不要出現省略一個參數類型,不省略一個參數類型。

Lambdas lambda1 = (a,b) -> {  };

2.參數小括號

如果參數列表中,參數的數量只有一個,此時小括號可以省略。

Lambdass lambda2 = a -> {   };

3.方法大括號

如果方法體中只有一條語句,此時大括號可以省略。

Lambdasss lambda3 = a -> System.out.println();

如果方法體中唯一的一條語句是個返回語句,則在省略掉大括號的同時,也必須省略掉return。

Lambdassss 	lambda4 = a -> 10;
LambdaS 	lambda5 = (a,b) -> a+b;

四、Lambda語法進階

1.方法引用

可以快速的將一個Lambda表達式的實現指向一個已經實現的方法。
語法: 方法的隸屬者::方法名

方法隸屬者:如果這個方法是靜態的方法,則方法的隸屬者爲類;若是動態方法,隸屬者爲類的對象。

注意:參數數量和類型一定要和接口中定義的方法一致;返回值的類型一定要和接口中定義的方法一致。

public class Test{
	public static void main(String[] args){
		Lambdas lambda1	 = a -> change(a);
		Lambdass lambda2 = Test::change;//引用了change方法的實現。
	}
	
	private static int change(int a){
		return a * 2;
	}
}

2.構造方法引用

public class Test{
	public static void main(String[] args){
		StudentCreater lambda1 = () -> { return new Student };
		StudentCreater lambda1 = () -> new Student;
		StudentCreater lambda1 = Studeng::new; 	//無參構造方法引用-----
		
		StudentCreater2 lambda2 = Studeng::new; //有參構造方法引用-----
		Studengt s = lambda2.getStudent("Tom",12);//賦值
	}
}

interface StudentCreater{
	Student getStudent();
}

interface StudentCreater2{
	Student getStudent(String name,int age);
}

public class Student {
	public String name;
	public int age;
	public Student (){}
	public Studnet (String name,int age){
		this.name = name;
		this.age = age;
	}
}

五、Lambda綜合

在一個ArrayList中有若干個Student對象,按年齡排序

public class Test {
	public static void main(String[] args){
		ArrayList<Student> list = new ArrayList<Student>();
		list.add(new Student("Tom",11));
		list.add(new Student("Lily",44));
		list.add(new Student("Jak",33));
		list.add(new Student("Anny",22));
		list.add(new Student("Jey",55));

		list.sort((o1,o2) -> {
			return o2.age - o1.age;
		});

		list.sort((o1,o2) -> o2.age - o1.age;

	}
}
public class TestTreeSet {
	public static void main(String[] args){
		//使用Lambda表達式實現Comparator接口,並實列化一個TreeSet對象
		TreeSet<Student> set = new TreeSet<Student>((o1,o2) -> o2.age - o1.age );
		set.add(new Student("Tom",11));
		set.add(new Student("Lily",44));
		set.add(new Student("Jak",33));
		set.add(new Student("Anny",22));
		set.add(new Student("Jey",55));
	}
}

集合的遍歷(forEach):

public class Test {
	public static void main(String[] args){
		ArrayList<Integer> list = new ArrayList<Integer>();
		Collections.addAll(list, 1,2,3,4,5);

		//將集合中的每一個元素都帶入到方法accept中
		list.forEach(System.out::println);

		//輸出集合中所有的偶數
		list.forEach( ele -> {
			if(ele%2 == 0){
			System.out.println(ele);
			}
		} );
		
	}
}

刪除集合中滿足條件的元素(remove):

public class Test {
	public static void main(String[] args){
		ArrayList<Student> list = new ArrayList<Student>();
		list.add(new Student("Tom",11));
		list.add(new Student("Lily",44));
		list.add(new Student("Jak",33));
		list.add(new Student("Anny",22));
		list.add(new Student("Jey",55));

		//刪除年齡大於30的
		ListIterator<Student> it = list.listIterator();
		while(it.hasNext()){
			Student s = it.next();
			if(ele.age > 30){
				it.remove();
			}
		}
		
		//Lambda實現
		list.removeif( ele -> ele.age > 30);//將集合中的每一個元素都帶入到test方法中,如果返回值是true,則刪除這個元素。

}

開闢一條線程,做數字123的輸出:

public class Test {
	public static void main(String[] args){
	Thread t = new Thread( () -> {
		System.out.print("123");
	} );
	t.start();
	}
}

六、系統內置函數式接口

import java.util.function.*

Predicate<T>   boolean test(T t)
參數:T  返回值:boolean
	IntPredicate   int -> boolean
	DoublePredicate   double -> boolean
BiPreadicate<T,U>  
參數:T,U  返回值:boolean
Consumer<T>  void accept(T t)
參數:T  返回值:void
	IntConsumer int -> void
	DoubleConsumer double -> void
BiConsumer<T,U>  
參數:T,U  返回值:void
Function<T, R>  R apply(T)
參數:T  返回值:R
BiFunction<T,U,R>  
參數:T,U  返回值:R
Supplier<T>  T get();
參數:無  返回值:T
UnaryOperator<T>  
參數:T  返回值:T
BinaryOperator<T>  
參數:T,T  返回值:T

七、Lambda閉包問題

提升變量的生命週期

public class ClosureDemo{
	public static void main(String[] args){
		int n = getNumber().get();
	}
	
	private static Supplie<Integer> getNumber(){
		int num =10;
		return () -> {
			return num;
		}
	}
}

在閉包中會默認加上final修飾

public class ClosureDemo{
	public static void main(String[] args){
		int a = 10; //final
		Consumer<Integer> c = ele -> {
			System.out.println(a);
		}
		a++;
		c.accept(1);
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章