java8 中引入的 Lambda 表达式真的是个好东西,掌握之后,写代码更简洁了,码字效率也提升了不少,这里咱
们一起来看看 Lambada 表达式常见的写法,加深理解。
@FunctionalInterface
public interface Fun {
void print(String s1, String s2);
}
创建 Fun 有 8 种写法。
Fun fun1 = new Fun() {
@Override
public void print(String s1, String s2) {
String msg = s1 + "," + s2;
System.out.println(msg);
}
};
Fun fun2 = (String s1,String s2) -> {
String msg = s1 + "," + s2;
System.out.println(msg);
};
Fun fun3 = (s1, s2) -> {
String msg = s1 + "," + s2;
System.out.println(msg);
};
Fun fun4 = (s1, s2) -> System.out.println(s1 + "," + s2);
添加一个静态方法
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);
若静态方法的参数和函数式接口的方法参数一致,可以对下面代码继续优化
Fun fun5 = (s1, s2) -> StaticMethod.print(s1,s2);
可以优化为下面这样
Fun fun6 = StaticMethod::print;
添加一个实例对象,内部添加一个实例方法
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);
若实例方法的参数和函数式接口的方法参数一致,可以对下面代码继续优化
Fun fun7 = (s1, s2) -> instanceMethod.print(s1,s2);
优化为下面这样
Fun fun8 = instanceMethod::print;
@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 种方式,下面来看各种方式演化的过程。
@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 种创建方式类似,第一种是第二种的简写。
//方式9:类::new的方式
UserFun fun9 = User::new;
//这个相当于
UserFun fun10 = new UserFun(){
@Override
public User createUser() {
return new 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);
}
}
//方式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);
}
};
Runnable a1 = () -> System.out.println("Hello");
new Thread(a1).start();
a1.run();
下面这个案例比较特殊,下面列出了 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;
}
}
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);
}
}
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();
}
}
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);
}
}
Runnable a1 = () -> System.out.println("Hello");
new Thread(a1).start();
a1.run();