Lambda表达式用法汇总
Lambda表达式用法汇总
java8 中引入的 Lambda 表达式真的是个好东西,掌握之后,写代码更简洁了,码字效率也提升了不少,这里咱
们一起来看看 Lambada 表达式常见的写法,加深理解。
1、有参无返回值函数式接口 8 种写法
1.1、先来定义一个函数式接口
- 有 2 个参数
- 无返回值
@FunctionalInterface
public interface Fun {
void print(String s1, String s2);
}
创建 Fun 有 8 种写法。
1.2、第 1 种:原始的写法如下
Fun fun1 = new Fun() {
@Override
public void print(String s1, String s2) {
String msg = s1 + "," + s2;
System.out.println(msg);
}
};
1.3、第 2 种:Lambda 方式完整写法
Fun fun2 = (String s1,String s2) -> {
String msg = s1 + "," + s2;
System.out.println(msg);
};
1.4、第 3 种:Lambda 方式隐藏参数类型
Fun fun3 = (s1, s2) -> {
String msg = s1 + "," + s2;
System.out.println(msg);
};
1.5、第 4 种:Lambda 方式单行可去掉{}
Fun fun4 = (s1, s2) -> System.out.println(s1 + "," + s2);
1.6、第 5 种:Lambda 方式引用静态方法
添加一个静态方法
public static class StaticMethod {
public static void print(String s1, String s2) {
String msg = s1 + "," + s2;
System.out.println(msg);
}
}
继续简写 Fun,如下
Fun fun5 = (s1, s2) -> StaticMethod.print(s1,s2);
1.7、第 6 种:Lambda 方式使用::引用静态方法,隐藏参数
若静态方法的参数和函数式接口的方法参数一致,可以对下面代码继续优化
Fun fun5 = (s1, s2) -> StaticMethod.print(s1,s2);
可以优化为下面这样
Fun fun6 = StaticMethod::print;
1.8、第 7 种:Lambda 方式引用实例方法
添加一个实例对象,内部添加一个实例方法
public static class InstanceMethod {
public void print(String s1, String s2) {
String msg = s1 + "," + s2;
System.out.println(msg);
}
}
继续简写 Fun,如下
InstanceMethod instanceMethod = new InstanceMethod();
Fun fun7 = (s1, s2) -> instanceMethod.print(s1,s2);
1.9、第 8 种:Lambda 方式使用::实例态方法,隐藏参数
若实例方法的参数和函数式接口的方法参数一致,可以对下面代码继续优化
Fun fun7 = (s1, s2) -> instanceMethod.print(s1,s2);
优化为下面这样
Fun fun8 = instanceMethod::print;
2、无参有返回值函数式接口 8 种写法
2.1、来一个有返回值的函数式接口
- 函数式接口 UserFun 中有个 createUser 方法用来创建 User 对象
- User 类有 2 个属性,定义了 2 个构造方法
- StaticMethod 提供了一个静态方法 user()用来创建 User 对象
- InstanceMethod 提供了一个实例方法 user()用来创建 User 对象
@FunctionalInterface
public interface UserFun {
User createUser();
}
public static class User {
private String name;
private Integer age;
public User() {
}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
}
public static class StaticMethod {
public static User user() {
return new User("张三", 30);
}
}
public static class InstanceMethod {
public User user() {
return new User("张三", 30);
}
}
创建 UserFun 有 8 种方式,下面来看各种方式演化的过程。
2.2、创建 UserFun 的 8 种写法
@Test
public void test1() {
//方式1:原始方式
UserFun fun1 = new UserFun() {
@Override
public User createUser() {
return new User("张三", 30);
}
};
//方式2:Lambda玩转方式()->{方法体;}
UserFun fu2 = () -> {
return new User("张三", 30);
};
//方式3:方法体只有一行,可去掉{}
UserFun fun3 = () -> new User("张三", 30);
//方式4:调用静态方法
UserFun fun4 = () -> {
return StaticMethod.user();
};
//方式5:去掉{}
UserFun fun5 = () -> StaticMethod.user();
//方式6:使用::调用静态方法
UserFun fun6 = StaticMethod::user;
InstanceMethod instanceMethod = new InstanceMethod();
//方式7:实例方法
UserFun fun7 = () -> instanceMethod.user();
//方式8:实例对象::实例方法
UserFun fun8 = instanceMethod::user;
}
2.3、第 9 种方式:类::new 的
代码如下,下面 2 种创建方式类似,第一种是第二种的简写。
//方式9:类::new的方式
UserFun fun9 = User::new;
//这个相当于
UserFun fun10 = new UserFun(){
@Override
public User createUser() {
return new User();
}
};
3、有参有返回值的函数式接口
3.1、来一个有参、有返回值的函数式接口
- 函数式接口 UserFun 中有个有参的 createUser(String name,Integer age)方法用来创建 User 对象
- User 类有 2 个属性,定义了 1 个有参构造方法
- StaticMethod 提供了一个静态方法 user(String name,Integer age)用来创建 User 对象
- InstanceMethod 提供了一个实例方法 user(String name,Integer age)用来创建 User 对象
@FunctionalInterface
public interface UserFun {
User createUser(String name, Integer age);
}
public static class User {
private String name;
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
}
public static class StaticMethod {
public static User user(String name, Integer age) {
return new User(name, age);
}
}
public static class InstanceMethod {
public User user(String name, Integer age) {
return new User(name, age);
}
}
3.2、创建 UserFun 的 11 种写法
//方式1:原始方式
UserFun fun1 = new UserFun() {
@Override
public User createUser(String name, Integer age) {
return new User(name, age);
}
};
//方式2:Lambda玩转方式()->{方法体;}
UserFun fun2 = (String name, Integer age) -> {
return new User(name, age);
};
//方式3:方法体只有一行,可去掉{}
UserFun fun3 = (String name, Integer age) -> new User("张三", 30);
//方式4:隐藏参数类型
UserFun fun4 = (name, age) -> new User("张三", 30);
//方式5:调用静态方法
UserFun fun5 = (String name, Integer age) -> {
return StaticMethod.user(name, age);
};
//方式6:隐藏参数类型,单行可以去掉{}和return
UserFun fun6 = (name, age) -> StaticMethod.user(name, age);
//方式7:使用::调用静态方法,参数类型数量需要和静态方法一致
UserFun fun7 = StaticMethod::user;
InstanceMethod instanceMethod = new InstanceMethod();
//方式8:调用实例方法
UserFun fun8 = (String name, Integer age) -> {
return instanceMethod.user(name, age);
};
//方式9:隐藏参数类型,单行可以去掉{}和return
UserFun fun9 = (name, age) -> instanceMethod.user(name, age);
//方式10:使用::调用静态方法,参数类型数量需要和实例方法一致
UserFun fun10 = instanceMethod::user;
//方式11:类::new的方式,函数接口中的方法参数需要和User类中构造方法的参数类型数量一致
UserFun fun11 = User::new;
//这个相当于
UserFun fun12 = new UserFun(){
@Override
public User createUser(String name,Integer age) {
return new User(name,age);
}
};
4、无参无返回值
Runnable a1 = () -> System.out.println("Hello");
new Thread(a1).start();
a1.run();
5、特殊案例
下面这个案例比较特殊,下面列出了 5 种写法,这几种写法效果是一样的。
方式 5 比较特殊,注意看注释,大家领会领会。
public class LambdaTest4 {
@FunctionalInterface
public interface Fun {
String dispose(String s1, String s2);
}
@Test
public void test1() {
//方式1:原始写法
Fun fun1 = new Fun() {
@Override
public String dispose(String s1, String s2) {
return s1.concat(s2);
}
};
//方式2:lambda玩转写法
Fun fun2 = (String s1, String s2) -> {
return s1.concat(s2);
};
//方式3:单行可以隐藏{}和return
Fun fun3 = (String s1, String s2) -> s1.concat(s2);
//方式4:隐藏参数
Fun fun4 = (s1, s2) -> s1.concat(s2);
/**
* 方式5:类::方法,这种写法需要满足
* 1、函数接口方法的第1个参数类型需要和{类名::方法}中的类名是同种类型
* 2、第1个参数后面的参数将作为{类名::方法}中方法的参数,注意下面的concat方法只有1个参数
*/
Fun fun5 = String::concat;
}
}
6、使用
6.1、有参无返回值函数式接口
package com.example.lambdatest;
/**
* @author zhangshixing
* 有参无返回值函数式接口
*/
public class Test1 {
public static void main(String[] args) {
Fun fun = (String s1, String s2) -> {
String msg = s1 + "," + s2;
System.out.println(msg);
};
// hello,world
fun.print("hello", "world");
}
@FunctionalInterface
public interface Fun {
void print(String s1, String s2);
}
}
6.2、无参有返回值函数式接口
package com.example.lambdatest;
/**
* @author zhangshixing
* 无参有返回值函数式接口
*/
public class Test2 {
public static void main(String[] args) {
Fun fun = () -> "Hello,World";
String returnStr = fun.getNumber();
System.out.println(returnStr);
}
@FunctionalInterface
public interface Fun {
String getNumber();
}
}
6.3、有参有返回值的函数式接口
package com.example.lambdatest;
/**
* @author zhangshixing
* 有参有返回值的函数式接口
*/
public class Test3 {
public static void main(String[] args) {
Fun fun = (a, b) -> a + b;
int result = fun.add(1,2);
System.out.println(result);
}
@FunctionalInterface
public interface Fun {
int add(int a, int b);
}
}
6.4 无参无返回值
Runnable a1 = () -> System.out.println("Hello");
new Thread(a1).start();
a1.run();