lambda表达式
jdk1.8推出的新特性,作用: 可以简化匿名内部类的使用
前提:函数式接口
函数式接口: 抽象方法只有一个的接口(接口中必须要重写的方法只有一个)
检查函数式接口: @FunctionalInterface
语法:
()->{}
( ): 重写的抽象方法的参数列表
->: 箭头符号, lambda 符号,箭头函数,具有上下文推到的作用
{ }: 重写的方法的方法体
public class LambdaDemo {
public static void main(String[] args) {
//匿名内部类的写法
/*Smoke s=new Smoke(){
@Override
public void smoking() {
System.out.println("边吸烟一遍吐烟圈...");
}
};*/
//lambda写法1:
/*Smoke s=()->{
System.out.println("边吸烟一遍吐心形烟圈...");
};*/
//lambda写法2: 当方法体语句只有一句的时候,前后的{}可以省略
//Smoke s=()->System.out.println("边吸烟一遍吐星星烟圈...");
//lambda写法3: 如果方法有参数,参数的数据类型可以省略
//Smoke s=(a,b)->System.out.println("边吸烟一遍吐星星烟圈..."+a);
//lambda写法4: 如果方法有参数,参数的个数只有一个,前后的()也可以省略
//Smoke s= a ->System.out.println("边吸烟一遍吐星星烟圈..."+a);
//lambda写法5: 如果方法有返回值类型,并且方法体只有一个return语句的时候,前后的{}+return关键字可以一起省略
/*Smoke s= a ->{
System.out.println("边吸烟一遍吐星星烟圈..."+a);
return "你好就好";
};*/
Smoke s= a ->"你好就好";
System.out.println(s.smoking(10));
//lambda可以当做方法的参数使用,前提形参的类型为一个函数式接口
test(a ->"你好就好");
}
static void test(Smoke s){
System.out.println(s.smoking(111));
}
}
//函数式接口
@FunctionalInterface
interface Smoke{
String smoking(int a);
}
四大内置核心函数式接口消费性接口
Consumer
void accept(T t)
供给型接口
Supplier
T get()
函数型接口
Function<T,R>
R apply(T t)
断定型接口
Predicate
boolean test(T t)
前3种接口的具体操作代码,没有用主方法实现,使用的是@Test
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import org.junit.Test;
public class Practice06 {
/*
* 消费性接口 Consumer<T>
void accept(T t)
*/
//@Test 是直接使用Junit运行的,不需要在主方法里使用
@Test
public void test1(){
happy(1000,(t)->{System.out.println("张三打麻将消费"+t);});//lambda表达式
happy(100,(t)->{System.out.println("李四打麻将消费"+t);});
}
//参数1:消费金额 参数2:消费方式
public void happy(int money,Consumer<Integer> con){
con.accept(money);//接受
}
/* 函数型接口 Function<T,R>
R apply(T t)
*/
@Test
public void test2(){
System.out.println(strHander(" haha ",(t)->t.trim()));//trim是去除前后空格
}
//对字符串进行某种操作
public String strHander(String str,Function<String,String>fun){
return fun.apply(str);//fun是Function 的变量
}
/* 供给型接口 Supplier<T>
T get()
*/
@Test
public void test3(){
List ls=get(10,()->(int)(Math.random()*(5-2+1)+2));
System.out.println(ls);
}
//按照一定规则,差生指定个数的数据,返回存着数据的容器
public List<Integer> get(int num,Supplier<Integer> sup){
List<Integer> list=new ArrayList();//泛型容器
for(int i=1;i<=num;i++){
list.add(sup.get());
}
return list;
}
}
方法引用
简化Lambda表达式,可以理解为Lambda表达式的另一种表现形式
前提: 重写的抽象方法 方法体的实现,其实就是通过调用另外一个已有的方法进行实现,可以通过方法引用进行调用,简化Lambda的写法
对象的引用 : :成员方法 ; (是两个冒号,但是不怎么明显?!)
类名: :静态方法名;
类名::成员方法;
要求: 函数型接口的抽象方法的参数列表和返回值要求与内部引用的方法的参数列表和返回值保持一致!
构造器引用:
new Person();
Person::new;
类型::::new;
用的是@Test
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import org.junit.Test;
import com.shsxt.testLambda02.Employee;
public class Test02 {
/*
* 构造器引用
*/
@Test
public void test5(){
// Supplier<Employee> sup=()->new Employee();
Supplier<Employee> sup=Employee::new;
Function<Integer,Employee> fun=(i)->new Employee(i);
Function<Integer,Employee> fun2=Employee::new;
}
/*
* 类名::成员方法;
* 如果抽象方法只有一个参数,作为调用|引用的方法的对象
* 如果抽象方法有两个参数,第一个作为调用方法的对象,第二个开始作为调用方法的参数
*/
@Test
public void test4(){
// BiPredicate<String, String> bi=(s1,s2)-> s1.equals(s2);
BiPredicate<String, String> bi=String::equals;
System.out.println(bi.test("zhangsan","zha2ngsan"));;
}
/*
* 类名::静态方法名;
* 抽象方法的参数列表与引用的方法的参数列表保持一致,返回值保持一致
*/
@Test
public void test3(){
// Comparator<Integer> com=(d1,d2)->{return Integer.compare(d1, d2);};
Comparator<Integer> com=Integer::compare;
System.out.println(com.compare(1, 2));;
}
/*
* 对象的引用::成员方法->简化Lambda结构
*/
@Test
public void test2(){
List<String> ls=Arrays.asList("aa","bb","cc","dd");
//ls.forEach((e)->{System.out.println(e)});
ls.forEach(System.out::println);
}
@Test
public void test1(){
PrintStream p=System.out;
// Consumer com=(e)->{System.out.println(e);};
// Consumer com=(e)->{p.println(e);};
Consumer com=System.out::println;
com.accept("haha");
com.accept("hehe");
com.accept("heihei");
com.accept("houhou");
}
}