体验lambda表达式
正常语句:
public class LambdaTest {
public static void main(String[] args) {
Test test = new Test() {
@Override
public int add(int a, int b) {
System.out.println("a===="+a+",b====="+b);
return 0;
}
};
test.add(1,2);
}
interface Test{
int add(int a,int b);
}
}
lambda表达式
public class LambdaTest {
public static void main(String[] args) {
// Test test = new Test() {
// @Override
// public int add(int a, int b) {
// System.out.println("a===="+a+",b====="+b);
// return 0;
// }
// };
Test test = (int a,int b)->{
System.out.println("a===="+a+",b====="+b);
return 0;
};
test.add(1,2);
}
interface Test{
int add(int a,int b);
}
}
1. Lambda表达式介绍
Lambda 表达式是Java 8引入的重要新特性。
Lambda 表达式简化了匿名内部类的形式,并且可以达到同样的效果(当然Lambda 要优雅得多)。虽然最终达到的效果是一样的,但其底层实现原理却并不相同。匿名内部类在编译之后会创建一个新的匿名内部类出来,而 Lambda 是调用 JVM invokedynamic指令实现的,并不会产生新类。
Lambda表达式返回的是接口对象实例。
其基本语法如下:
(参数列表) -> {
方法体
};
->
是Lambda运算符,英文名是goes to
2. Lambda表达式语法
接口参数和返回值多种情况举例:
public class LambdaTest {
public static void main(String[] args) {
Test1 t1 = () -> {
System.out.println("无返回值、无参数");
};
Test2 t2 = (int a) -> {
System.out.println("无返回值,单个参数 a=" + a);
};
Test3 t3 = (int a, int b) -> {
System.out.println("无返回值,多个参数 a=" + a + ",b=" + b);
};
Test4 t4 = () -> {
System.out.println("有返回值、无参数");
return 4;
};
Test5 t5 = (int a) -> {
System.out.println("有返回值,单个参数 a=" + a);
return 5;
};
Test6 t6 = (int a, int b) -> {
System.out.println("有返回值,多个参数 a=" + a + ",b=" + b);
return 6;
};
t1.method();
t2.method(5);
t3.method(5,10);
System.out.println(t4.method());
System.out.println(t5.method(5));
System.out.println(t6.method(5, 10));
}
/**
* 无返回值、无参数
*/
interface Test1 {
void method();
}
/**
* 无返回值,单个参数
*/
interface Test2 {
void method(int a);
}
/**
* 无返回值,多个参数
*/
interface Test3 {
void method(int a, int b);
}
/**
* 有返回值、无参数
*/
interface Test4 {
int method();
}
/**
* 有返回值,单个参数
*/
interface Test5 {
int method(int a);
}
/**
* 有返回值,多个参数
*/
interface Test6 {
int method(int a, int b);
}
}
3.Lambda表达式精简语法
-
参数类型可以省略
比如
Test2 t2 = (int a) -> {System.out.println(...);};
可以写成Test2 t2 = (a) -> {System.out.println(...);};
-
假如只有一个参数,那么
()
括号可以省略比如
Test2 t2 = (int a) -> {System.out.println("无返回值,单个参数 a=" + a);};
可以写成Test2 t2 = a -> {System.out.println(...);};
-
假如方法体只有一条语句,那么语句后的
;
分号和方法体的{}
大括号可以一起省略比如
Test2 t2 = a -> {System.out.println(...);};
可以写成Test2 t2 = a -> System.out.println(...);
-
如果方法体中唯一的语句是return返回语句,那么在省略第3种情况的同时,
return
也必须一起省略比如
Test5 t5 = a -> {return 1;};
可以写成``Test
5 t5 = a -> 1;`
4.方法引用
方法引用语法
-
如果是实例方法:
对象名::实例方法名
-
如果是静态方法:
类名::实例方法名
-
如果是构造方法:
类名::new
实例方法引用
public class Test {
public void eat(int a) {
System.out.println("吃东西。" + "a=" + a);
}
public static void main(String[] args) {
//Lambda表达式写法:
Dog dog1 = (a) -> System.out.println("吃东西。" + "a=" + a);
Cat cat1 = (a) -> System.out.println("吃东西。" + "a=" + a);
dog1.doSomething(5);
cat1.doSomething(5);
//方法引用写法:
Test test = new Test();
Dog dog2 = test::eat;
Cat cat2 = test::eat;
dog2.doSomething(10);
cat2.doSomething(10);
}
}
@FunctionalInterface
interface Dog {
void doSomething(int a);
}
@FunctionalInterface
interface Cat {
void doSomething(int a);
}
构造方法引用
如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现(比如说接口方法与这个构造方法的参数个数、参数类型和返回值都对的上),那么就可以使用构造方法引用。
public class Test {
public void eat(int a) {
System.out.println("吃东西。" + "a=" + a);
}
public static void main(String[] args) {
//Lambda表达式写法:
DogService dogService1 = (name, age) -> new Dog(name, age);
System.out.println(dogService1.getDog("大狗", 5));
//方法引用写法:
DogService dogService2 = Dog::new;
System.out.println(dogService2.getDog("二狗", 3));
}
}
@FunctionalInterface
interface DogService {
Dog getDog(String name, int age);
}
class Dog {
String name;
int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}