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);
}
}