一 Lambda简介
什么是Lamba表达式?
Lambda是JAVA8添加的新特性,Lambda就是一个匿名函数。
为什么使用Lambda表达式?
使用Lambda表达式可以对一个接口进行非常简洁的实现
Lambda表达式对接口的要求?
虽然可以使用Lambda表达式对某些接口进行简洁的实现,但是并不是所有的接口都可以使用Lambda来实现。
Lambda表达式要求接口中定义的必须要实现的抽象方法只能是一个。
备注:在JAVA8中新增加了一个对接口的特性 default 参考链接 : java8中的default关键字
@FunctionalInterface
用于修饰函数式接口,接口中的抽象方法只有一个
package com.learn.learn001;
//比较两个数的大小
public class Proggram {
public static void main(String[] args) {
//1.使用接口实现类的形式
Comparator comparator = new MyComparator();
//2,使用匿名内部类的形式
Comparator comparator1 = new Comparator() {
@Override
public int compare(int a, int b) {
return a-b;
}
};
//3.使用Lambda的实现实现接口
Comparator comparator2 = (a,b) -> a-b;
}
}
class MyComparator implements Comparator{
@Override
public int compare(int a, int b) {
return a-b;
}
}
@FunctionalInterface
interface Comparator{
int compare(int a,int b);
}
二 Lambda基础语法
Lambda是一个匿名函数
参数列表 方法体
() : 参数列表
{} : 方法体
-> : Lambda 运算符 goes to
package com.learn.learn2;
import com.learn.interfaces.*;
public class Syntax1 {
public static void main(String[] args) {
//Lambda的基础语法
//Lambda是一个匿名函数
//参数列表 方法体
//() : 参数列表
//{} : 描述方法体
//-> : Lambda 运算符 goes to
//无参无返回
LambdaNoneReturnNoneParameter lambda1 = () ->{
System.out.println("无参无返回");
};
lambda1.test();
//无返回值 单个参数
LambdaNoneReturnSingleParameter lambda2 = (int a) ->{
System.out.println("无返回值 单个参数:"+a);
};
lambda2.test(666);
//无返回值多个参数
LambdaNoneReturnMutipleParameter lambda3 = (int a,int b) ->{
System.out.println("无返回值 单个参数 a:"+a+" b:"+b);
};
lambda3.test(666,999);
//有返回值 无参数
LambdaSingleReturnNoneParameter lambda4 = () ->{
return (111);
};
System.out.println(lambda4.test());
//有返回值 单个参数
LambdaSingleReturnSingleParameter lambda5 = (int a) ->{
return (111+a);
};
System.out.println(lambda5.test(222));
//有返回值 多个参数
//有返回值 单个参数
LambdaSingleReturnMutipleParameter lambda6 = (int a,int b) ->{
return (a+b);
};
System.out.println(lambda6.test(222,333));
}
}
三 语法精简
1. 参数类型:
由于在接口的抽象方法中,已经定义了参数的数量和类型,所以在Lambda表达式中,参数类型可以省略
备注:如果需要省略参数类型 ,则每一个参数类型都要省略,否则会报错。
2. 参数小括号
如果参数列表中,参数的数量只有一个,那么该参数可以省略。
3. 方法大括号
如果方法体中只有一条语句 此时大括号可以省略(例如:只有一句输出 )
4. return
如果方法体中,唯一的一条语句是返回语句,则在省略大括号的同时,必须省略掉 return 关键字
package com.learn.learn2;
import com.learn.interfaces.LambdaNoneReturnMutipleParameter;
import com.learn.interfaces.LambdaNoneReturnSingleParameter;
import com.learn.interfaces.LambdaSingleReturnMutipleParameter;
import com.learn.interfaces.LambdaSingleReturnNoneParameter;
public class Syntax2 {
public static void main(String[] args) {
// 语法精简
//1. 参数类型
//由于在接口的抽象方法中 已经定义了方法的数量和类型 所以在Lambda表达式中 参数类型可以省略
//备注: 如果需要省略类型 则每一个参数的类型都要省略 千万不要出现省略一个参数类型,不省略一个参数类型
LambdaNoneReturnMutipleParameter lam1 = ( a, b) ->{
System.out.println("省略全部参数类型");
};
//2. 参数小括号
// 如果参数列表中,参数数量只有一个,此时小括号可以省略
LambdaNoneReturnSingleParameter lam2 = a ->{
System.out.println("只有一个参数,参数小括号省略");
};
//3. 方法大括号
//如果方法中只有一条语句 此时大括号可以省略
LambdaNoneReturnSingleParameter lam3 = a->System.out.println("哈哈哈");
//4.如果方法体中 唯一的一个语句是一个返回语句 则在省略掉大括号的同时,必须省略掉return
LambdaSingleReturnNoneParameter lam4 = () -> 10;
LambdaSingleReturnMutipleParameter lam5= (a,b) -> a+b;
}
}
四 Lambda 语法进阶
方法引用:
可以快速的将一个Lambda表达式的实现指向一个已经实现的方法。
语法: 方法的隶属着 :: 方法名
注意:
1. 参数的数量和类型一定要与接口中定义的方法保持一致。
2. 返回值类型一定要与接口中定义的方法一致
package com.learn.learn2;
import com.learn.interfaces.LambdaSingleReturnSingleParameter;
public class Syntax3 {
public static void main(String[] args) {
//方法引用:
//可以快速的讲一个Lambda表达式的实现指向一个已经实现的方法。
//语法: 方法的隶属着 :: 方法名、
//注意
//1.参数的数量和类型一定要和接口中定义的方法保持一致
//2.返回值的类型一定要和接口中定义的方法一致
LambdaSingleReturnSingleParameter lam1 = a -> change(a);
System.out.println(lam1.test(111));
//方法的引用 引用了change方法的使用
LambdaSingleReturnSingleParameter lam2 = Syntax3::change;
System.out.println(lam2.test(222));
}
private static int change(int a){
return a*2;
}
}
package com.learn.learn2;
import com.learn.data.Person;
public class Syntax4 {
public static void main(String[] args) {
// PersonCreator personCreator = () -> new Person();
//构造方法的引用
PersonCreator personCreator1 = Person::new;
Person a = personCreator1.getPerson();
PersonCreator2 personCreator2 = Person::new;
personCreator2.getPerson("小明",5);
}
}
//需求:
interface PersonCreator {
Person getPerson();
}
interface PersonCreator2 {
Person getPerson(String name,int age );
}
package com.learn.data;
public class Person {
public String name;
public int age;
public Person() {
System.out.println("person类的无参构造方法执行了");
}
public Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("person类的有参构造方法执行了");
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
五 Lambda综合案例
package com.learn.exercise;
import com.learn.data.Person;
import java.util.ArrayList;
import java.util.List;
public class Exercise1 {
//集合排序
//ArrayList<>
public static void main(String[] args) {
//已知:在一个ArrayList有若干个person对象,将这些person对象按照年龄进行降序排列
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("小明",10));
personList.add(new Person("张三",11));
personList.add(new Person("小赵",9));
personList.add(new Person("小龙",12));
personList.add(new Person("小冰",9));
personList.add(new Person("小黄",3));
//排序
personList.sort( (o1,o2) -> o2.age -o1.age );
System.out.println(personList);
}
}
package com.learn.exercise;
import com.learn.data.Person;
import java.util.TreeSet;
public class Exercise2 {
public static void main(String[] args) {
//TreeSet 可以对集合中的元素做一个自带的排序
//使用LAmbda表达式来实现Comparator接口并实例化一个TreeSet对象
TreeSet<Person> set = new TreeSet<Person>( (o1,o2) -> {
//相等会被去重 所以增加判断条件
if (o1.age>o2.age)
return -1;
else
return 1;
} );
set.add(new Person("小明",10));
set.add(new Person("张三",11));
set.add(new Person("小赵",9));
set.add(new Person("小龙",12));
set.add(new Person("小冰",9));
set.add(new Person("小黄",3));
System.out.println(set);
}
}
package com.learn.exercise;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class Exercise3 {
public static void main(String[] args) {
//集合的遍历
List<Integer> list = new ArrayList<Integer>();
Collections.addAll(list,1,2,3,4,5,6,7);
//将集合中的每一个元素都带入到方法accept中,
//list.forEach(System.out :: println);
//输出集合中的所有偶数
list.forEach( ele ->{
if(ele%2 ==0){
System.out.println(ele);
}
});
}
}
package com.learn.exercise;
import com.learn.data.Person;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class Exercise4 {
public static void main(String[] args) {
//删除集合中满足条件的元素
List<Person> list = new ArrayList<Person>();
list.add(new Person("小明",10));
list.add(new Person("张三",11));
list.add(new Person("小赵",9));
list.add(new Person("小龙",12));
list.add(new Person("小冰",9));
list.add(new Person("小黄",3));
//删除集合中年龄大于10岁的元素
//迭代器实现
ListIterator<Person> iterator = list.listIterator();
while (iterator.hasNext()){
Person ele = iterator.next();
if(ele.age>10){
iterator.remove();
}
}
System.out.println(list);
//Lambda实现 removeIf--删除满足条件的元素
//将集合中的每一个元素带入到test中 如果返回值是true 则删除这个元素
list.removeIf( t -> t.age>10 );
}
}
package com.learn.exercise;
public class Exercise5 {
public static void main(String[] args) {
//开辟一个线程,做一个数字的输出
Thread t = new Thread(() -> {
for(int i =0;i<100;i++){
System.out.println(i);
}
});
t.start();
}
}
六 系统内置函数式接口
package com.learn.functional;
import java.util.function.*;
public class FunctionalInterface {
public static void main(String[] args) {
//系统内置的函数式接口
//Predicate<T> 参数 T 返回值 boolean
// IntPredicate int -> boolean
// LongPredicate long -> boolean
// DoublePredicate double ->boolean
//Consumer<T> : 參數 T 返回值 void
// IntConsumer int -> void
// LongConsumer long -> void
// DoubleConsumer double ->void
//Function : 參數 T 返回值 R (指定类型的参数和返回值)
// IntFunction<R> : int -> R
// LongFunction<R> : long -> R
// DoubleFunction<R> : double -> R
// IntToLongFunction int ->long
// IntToDoubleFunction int -> double
// LongToIntFunction long -> int
// LongToDoubleFunction long -> double
// DoubleToIntFunction double -> int
// DoubleToLongFunction double -> long
//Supplier<T> : 参数无 返回值 T
//UnaryOperator<T> : 参数 T 返回值 T
//BinaryOperator<T> : 参数 T,T 返回值 T
//BiFunction<T,U,R> : 参数是T ,U 返回值是R
//BiPredicate<T,U> : 参数: T,U 返回值 boolean
//BiConsumer<T,U> : 参数 T,U 返回值 void
//以后常用的接口 Predicate<T> Consume<T> Function(T,R) Supplier<T>
}
}
七 闭包