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();

你可能感兴趣的:(java,java)