lambda是一个匿名函数,可以把lambda表达式理解为一段可以传递的代码(将代码像数据一样传递下去)。可以写出更加简洁,灵活的代码。作为一种更紧凑的代码风格,使Java语言的表达能力得到了提升。
Java支持函数式编程,引入lambda表达式,lambda表达式是实现仅有一个抽象方法的接口的简化实现。
lambda表达式可以完全替代匿名内部类(只有一个抽象方法的情况下),并且没有匿名内部类这样繁琐的表达结构。
在接口中只定义一个抽象方法(可以有普通方法和静态方法)为后来的lambda表达式做准备的情况下,可以使用注解@FunctionalInterface,这样IDEA在编译阶段就会自动检测出接口中是否只有一个抽象方法,及时报错。
lambda表达式格式
lambda表达式的基础语法:JDK1.8中引入了一个新的操作符 “->”该操作符称为箭头操作符或lambda操作符,箭头操作符将lambda表达式拆分成两部分:
左侧:lambda表达式的参数列表
右侧:lambda表达式中所需执行的功能,即lambda体。
接口实现类类名 对象名=([接口中抽象方法的参数列表]) ->{
//抽象方法实现语句;
};
在lambda表达式所在的作用域中,参数列表中的参数名不能和作用域中的其他变量名冲突
lambda表达式中的参数个数和接口中抽象方法的参数个数对应。
public class Mytest2 {
public static void main(String[] args) {
Student1 student1 = new Student1() {
@Override
public void show(int a, int b) {
System.out.println(a + b);
}
};
System.out.println("-----------------------");
//简写代码第一步
Student1 student2 = (int a,int b) -> {
System.out.println(a + b);
};
//简写代码第二步
Student1 student3 = ( a, b) -> {
System.out.println(a + b);
};
//简写代码第三步
Student1 student4 = ( a, b) -> System.out.println(a + b);
//如果对于抽象方法的实现逻辑不少于一行,那么就不能省略大括号
Student1 student5 = (int a,int b) -> {
System.out.println(a - b);
System.out.println(a + b);
};
}
}
--------------------------
public interface Student1 {
public abstract void show(int a,int b);
}
public class Mytest3 {
public static void main(String[] args) {
ArrayList list = new ArrayList<>();
list.add("陕西省");
list.add("渭南市");
list.add("澄城县");
list.forEach(new Consumer() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
System.out.println("-----------------------");
//用lambda表达式代替上面的遍历
ArrayList list1 = new ArrayList<>();
list.add("陕西省");
list.add("渭南市");
list.add("澄城县");
list.forEach((String s) -> System.out.println(s));
}
}
public class Mytest {
public static void main(String[] args) {
Car car = new Car() {
@Override
public String drive(String Brand) {
return Brand;
}
};
System.out.println("--------------------");
//简写第一步
Car car1 = (String Brand) -> {
return Brand;
};
//简写第二步
Car car2 = (String Brand) -> Brand;
}
}
----------------------------------
public interface Car {
public abstract String drive(String Brand);
}
lambda表达式的核心在于:函数式接口
而函数式接口的核心在于:只有一个方法
实际上函数式变成分为以下四种接口:
(1)功能型函数式接口:public interface Function
(2)供给型函数式接口:public interface Supplier T get();
(3)消费性函数式接口:public interface Consumer void accept(T t);
(4)断言型函数式接口:public interface Predicate boolean test(T t);
函数式接口 | 参数类型 | 返回类型 | 用途 |
---|---|---|---|
Consumer 消费型接口 | T | void | 对类型为T的对象应用操作,包含方法:void accept(T,t) |
Supplier 供给型接口 | 无 | T | 返回类型为T的对象,包含方法:T get() |
Function |
T | R | 对类型为T的对象应用操作,并返回结果,结果是R类型的对象,包含方法:R apply(T t) |
Predicate 断言型接口 | T | boolean | 确定类型为T的对象是否满足某约束,并返回Boolean值,包含方法:boolean test(T t) |
public class Mytest2 {
public static void main(String[] args) {
//函数式接口:Consumer
Consumer consumer = new Consumer(){
@Override
public void accept(Integer a) {
System.out.println(a);
}
};
Consumer consumer1=(a)->System.out.println(a);
System.out.println("----------------------");
//函数式接口:Supplier
Supplier supplier = new Supplier(){
@Override
public Integer get() {
return null;
}
};
Supplier supplier1 = () -> null;
System.out.println("----------------------");
//函数式接口:Predicate
Predicate predicate = new Predicate(){
@Override
public Predicate and(Predicate other) {
return null;
}
@Override
public boolean test(String s) {
return false;
}
@Override
public Predicate negate() {
return null;
}
@Override
public Predicate or(Predicate other) {
return null;
}
};
System.out.println("------------------------");
//函数式接口:BinaryOperator
BinaryOperator binaryOperator = new BinaryOperator() {
@Override
public Integer apply(Integer a, Integer b) {
return a*b;
}
};
BinaryOperator binaryOperator2 = (a, b) -> a*b;
System.out.println("------------------------");
}
}
(1)当要传递给lambda体的操作,已经有实现的方法了,可以使用方法引用。
(2)方法引用可以看作是lambda表达式深层次的表达,换句话说,方法引用就是lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法,可以认为是lambda表达式的一个语法。
(3)要求:实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的 方法的参数列表和返回值类型保持一致。
(4)格式:使用操作符 “::” 将类(对象)与方法名分隔开来。
public class Mytest4 {
public static void main(String[] args) {
//Comparator 比较器接口
Comparator comparator = new Comparator() {
@Override
public int compare(Integer a, Integer b) {
return Integer.compare(a,b);
}
};
System.out.println("----------------------");
//lambda表达式
Comparator comparator1=(a,b)->Integer.compare(a,b);
System.out.println("----------------------");
//方法引用 类名::静态方法
Comparator comparator2=Integer::compareTo;
}
}
一个函数式接口,这个接口中要有两个参数,还要有返回值类型,BiFunction U是第一个参数,T是第二个参数,R是返回值类型。
public class Mytest2 {
public static void main(String[] args) {
//一个函数式接口,这个接口中要有两个参数,还要有返回值类型
//BiFunction U是第一个参数,T是第二个参数,R是返回值类型
BiFunction biFunction = new BiFunction() {
@Override
public Teacher apply(Integer integer, Double aDouble) {
/*Teacher teacher = new Teacher(integer, aDouble);
return teacher;*/
return new Teacher(integer,aDouble);
}
};
//第一步简化 lambda表达式
BiFunction biFunction1=(integer,adouble)->new Teacher(integer,adouble);
//第二步简化 方法引用 类名::重载方法
BiFunction biFunction2=Teacher::new;
}
}
---------------------------------
public class Teacher {
public Teacher(){
System.out.println("空参构造执行了!");
}
public Teacher(Integer age,Double salary){
System.out.println("有参构造执行了!");
}
}