Lambda表达式

  Lambda 表达式是 JDK1.8 的一个新特性,又称特殊的匿名内部类,可以取代大部分的匿名内部类,语法更简洁,可以写出更优雅的 Java 代码,可以极大地优化代码结构。

  Lambda 表达式不会生成单独的内部类文件,但匿名内部类会。


Lambda表达式特性

  ★ Lambda 表达式没有显示的方法名。

  ★ Lambda 表达式很像一个函数,具有参数列表、函数体、返回类型、异常,但没有函数名。

  ★ Lambda 表达式可以作为方法的参数,也可以作为变量存储。

  ★ Lambda 表达式的代码更加简洁和精确。


Lambda表达式的定义

基本语法:

  或

注意事项:

  ✔ Lambda 表达式由三部分构成:参数列表、箭头(->)、Lambda 体。

  ✔ Lambda 体,可以是一个表达式,也可以是一个语句块。

  ✔ Lambda 体,表达式中不能加入 return 语句,因为在表达式中已经隐含了 return 语句;但是,语句块中没有隐含,需要使用 return 语句。

  ✔ Lambda 表达式并不是对所有接口都可以实现,接口需要满足一个条件才能被Lambda 表达式实现:Lambda 规定接口中只能有一个需要被实现的方法。注意,并不是规定接口中只能有一个方法。


Lambda 表达式的使用

1.无参,有返回值

@FunctionalInterface
public interface LambdaTest {
    // 无参,有返回值
    int method();
}
public class test {

    public static void main(String[] args) {

        LambdaTest test = ()-> 20;

        int result = test.method();

        System.out.println(result);
    }
}

2.无参,无返回值

@FunctionalInterface
public interface LambdaTest {
    // 无参,无返回值
    void method();
}
public class test {

    public static void main(String[] args) {

        LambdaTest test = () -> {};

        test.method();

    }
}

3.单参,有返回值

@FunctionalInterface
public interface LambdaTest {
    // 单参,有返回值
    int method(int a);
}
public class test {

    public static void main(String[] args) {

        // 表达式形式
        LambdaTest test = a -> a+10;

        System.out.println(test.method(10));

        // 代码块形式
        LambdaTest test2 = a -> {
            return a+10;
        };

        System.out.println(test2.method(10));
    }
}

4.多参,有返回值

@FunctionalInterface
public interface LambdaTest {
    // 多参,有返回值
    int method(String a, String b);
}
public class test {

    public static void main(String[] args) {

        // 表达式形式
        LambdaTest test = (a, b) -> a.length() - b.length();

        System.out.println(test.method("abb", "bbccdd"));

        // 代码块形式
        LambdaTest test2 = (a, b) -> {
            return a.length() - b.length();
        };

        System.out.println(test2.method("abb", "bbccdd"));
    }
}

表达式使用技巧总结

  ★ 形参列表的数据类型会自动判断。

  ★ 如果形参列表为空,只需保留()。

  ★ 如果形参只有一个,()可以省略,只需要参数的名称即可。

  ★ 如果执行语句只有一句,且无返回值,则{}可省略;如果有返回值,若想省略{},则必须同时省略return,且执行语句也必须保证只有一句。


Lambda 表达式应用

方法引用

  有时候我们不是必须要自己重写某个匿名内部类的方法,我们可以可以利用 lambda表达式的接口快速指向一个已经被实现的方法。

引用语法:

常见形式:

引用要求:

  ① 参数数量和类型要与接口中定义的一致。

  ② 返回值类型要与接口中定义的一致。

代码示例:

public class MethodReferences {
    public static void main(String[] args) {
        // 1.对象::实例方法
        Consumer<String> consumer = s->System.out.println(s);
        consumer.accept("hello");

        Consumer<String> consumer2 = System.out::println;
        consumer2.accept("world");

        // 2.类::静态方法
        Comparator<Integer> com = (o1, o2)->Integer.compare(o1, o2);
        Comparator<Integer> com2 = Integer::compare;

        // 3.类::实例方法
        Function<String, String> function = e->e.toUpperCase();
        Function<String, String> function2 = String::toUpperCase;
        System.out.println(function2.apply("hello"));

        // 4.类::new
        Supplier<String> supplier = ()->new String();
        Supplier<String> supplier2 = String::new;
        System.out.println(supplier2.toString());
    }
}

创建线程

public class TestLambda {
    public static void main(String[] args) {
        // 匿名内部类
        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                System.out.println("子程序执行。。。");
            }
        };

        // Lambda表达式
        Runnable runnable2 = ()->System.out.println("子程序执行2。。。");
        new Thread(runnable2).start();
new Thread(()->System.out.println("子程序执行3。。。")).start(); } }

集合操作

  可以调用集合的 public void forEach(Consumer<? super E> action) 方法,通过 Lambda 表达式的方式遍历集合中的元素。Consumer 接口是 jdk 为我们提供的一个函数式接口。

public class test {

    // 集合遍历
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();

        Collections.addAll(list, 4, 3, 9, 0, 5);

        // 方法引用
        list.forEach(System.out::println);

        // Lambda表达式
        list.forEach(element -> {
            if (element % 2 == 0) {
                System.out.println(element);
            }
        });
    }
}
public class test {

    // 集合排序
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();

        Collections.addAll(list, 4, 3, 9, 0, 5);

        // 匿名内部类
        list.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }

        });

        // lambda表达式
        list.sort((o1,o2)->o1-o2);

        list.forEach(System.out::println);
    }
}
10-27 15:24