Lambda表达式介绍
Java8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁,通过Lambda表达式,可以替代我们以前经常写的匿名内部类来实现接口,Lambda表达式本质是一个匿名函数。
Lambda表达式语法
(int a,int b) -> (return a+b;)
Lambda表达式函数的话,只有参数列表和方法体
( 参数列表) -> {方法体}
( ):用来描述参数列表
{ }:用来描述方法体
->:Lambda运算符,可以叫做箭头符号,或者goes to
Lambda表达式语法细讲
public static void main(String[] args) {
If1 if1=()->{
System.out.println("无参数无返回值");
};
if1.test();
If2 if2=(int a)->{
System.out.println("单个参数无返回值 a=" +a);
};
if2.test(3);
If3 if3=(int a,int b)->{
System.out.println("两个参数无返回值 a+b=" + (a+b));
};
if3.test(1,5);
If4 if4=()->{
return 4;
};
System.out.println("无参数有返回值"+if4.test());
If5 if5=(int a)->{
return a;
};
System.out.println("单个参数有返回值" + if5.test(5));
If6 if6=(int a,int b)->{
return a-b;
};
System.out.println("多个参数有返回值" + if6.test(7,5));
}
interface If1{
/**
* 无参数无返回值
*/
void test();
}
interface If2{
/**
* 单个参数无返回值
* @param a
*/
void test(int a);
}
interface If3{
/**
* 两个参数无返回值
* @param a
* @param b
*/
void test(int a,int b);
}
interface If4{
/**
* 无参数有返回值
* @return
*/
int test();
}
interface If5{
/**
* 单个参数有返回值
* @param a
* @return
*/
int test(int a);
}
interface If6{
/**
* 多个参数有返回值
* @param a
* @param b
* @return
*/
int test(int a,int b);
}
Lambda表达式精简语法
1.参数类型可以省略
2.假如只有一个参数,( )括号可以省略
3.如果方法体只有一条语句,{ }大括号可以省略
4.如果方法体中唯一的语句是return返回语句,那省略大括号的同时return也要省略
Lambda01.If1 if1=()-> System.out.println("无参数无返回值");
if1.test();
Lambda01.If2 if2=a-> System.out.println("单个参数无返回值 a=" +a);
if2.test(3);
Lambda01.If3 if3=(a, b)-> System.out.println("两个参数无返回值 a+b=" + (a+b));
if3.test(1,5);
Lambda01.If4 if4=()->4;
System.out.println("无参数有返回值"+if4.test());
Lambda01.If5 if5=a->a;
System.out.println("单个参数有返回值" + if5.test(5));
Lambda01.If6 if6=(a, b)-> a-b;
System.out.println("多个参数有返回值" + if6.test(7,5));
方法引用
有时候多个Lambda表达式实现函数是一样的话,我们可以封装成通用方法,以便于维护;这时候可以用方法引用实现:
语法是:对象::方法
如果是static方法,可以直接用类名::方法
public class Lambda03 {
public static void main(String[] args) {
Lambda03 lambda03 = new Lambda03();
If5 if5 = lambda03::testA;
System.out.println(if5.test(3));
If5 if52 = lambda03::testA;
System.out.println(if52.test(5));
If5 if53 = Lambda03::testB;
System.out.println(if53.test(7));
If5 if54 = Lambda03::testB;
System.out.println(if54.test(9));
}
public int testA(int a){
return a-2;
}
public static int testB(int a){
return a-2;
}
interface If5{
int test(int a);
}
}
构造方法引用
如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用;
语法:类名::new
public static void main(String[] args) {
// DogService dogService=()->{
// return new Dog();
// };
// System.out.println(dogService.getDog());
// DogService dogService=()->new Dog();
// System.out.println(dogService.getDog());
DogService dogService=Dog::new;
System.out.println(dogService.getDog());
DogService02 dogService02=Dog::new;
System.out.println(dogService02.getDog("大黄",2));
}
interface DogService{
Dog getDog();
}
interface DogService02{
Dog getDog(String name,int age);
}
}
class Dog {
private String name;
private int age;
public Dog() {
System.out.println("无参构造方法");
}
public Dog(String name, int age) {
System.out.println("有参构造方法");
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
Lambda表达式集合排序和遍历集合
List<Dog> list = new ArrayList<>();
list.add(new Dog("aa",1));
list.add(new Dog("bb",4));
list.add(new Dog("cc",3));
list.add(new Dog("dd",2));
list.add(new Dog("ee",5));
System.out.println("Lambda表达式集合排序");
//list.sort((o1,o2)->{return o1.getAge()-o2.getAge();});
list.sort((o1,o2)->o1.getAge()-o2.getAge());// 升序
System.out.println(list);
list.sort((o1,o2)->o2.getAge()-o1.getAge());// 降序
System.out.println(list);
System.out.println("Lambda表达式遍历集合");
list.forEach(System.out::println);// 遍历
@FunctionalInterface
@FunctionalInterface注解:
这个注解是函数式接口注解,所谓函数式接口,当然首先是一个接口,然后就是在这个接口里面只能有一个抽象方法
这种类型的接口也称为SAM接口,即Single Abstract Method interface
特点:
1.接口有且仅有一个抽象方法
2.允许定义静态方法
3.允许定义默认方法
4.允许java.lang.Object中的public方法
5.该注解不是必须的,如果一个接口符合“函数式接口”定义,那么加不加该注解都没有影响,加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但加上了@FunctionalInterface,那么编译器会报错
@FunctionalInterface
public interface TestInterface{
// 抽象方法
public void sub();
// java.lang.Object中的public方法
public boolean equals(Object var1);
// 默认方法
public default void defaultMethod(){
}
// 静态方法
public static void staticMethod(){
}
系统内置函数式接口
java8的推出,是以Lambda重要特性,一起推出的,其中系统内置了一系列函数式接口;
再jdk的java.util.function包下,有一系列的内置函数式接口: