【有书共读】Java攻略 读书笔记01

一、Lambda表达式简介
“Lambda 表达式”(lambda expression)是一个匿名函数,即没有函数名的函数;Lambda表达式不仅让代码变的简单、而且可读、最重要的是代码量也随之减少很多。
Java Lambda表达式的一个重要用法是简化某些匿名内部类(Anonymous Classes)的写法。
二、Lambda基础语法
基本语法:(parameters) -> expression或(parameters) ->{ statements; }

下面是一些Java lambda表达式的简单例子:

() -> 1  
// 1. 不需要参数,返回值为 1

x -> 3 * x  
// 2. 接收一个参数(数字类型),返回其3倍的值

(x, y) -> x + y  
// 3. 接受2个参数,并返回x+y

(int x, int y) -> x + y  
// 4. 接收2个int型整数,返回两值的和

(String s) -> System.out.print(s)
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)

三、lambda取代某些匿名内部类
下面介绍如何使用Lambda表达式简化匿名内部类的书写,但Lambda表达式并不能取代所有的匿名内部类,只能用来取代函数式接口(Functional Interface)的简写。
函数式接口是一种包含单一抽象方法(single abstract method)的接口。类通过为接口中的所有方法提供实现来实现任何接口,这可以通过顶级类、内部类甚至匿名内部类完成。
3.1 无参函数的简写
·例子1-1 Runnable接口的匿名内部类实现

public class  RunnableDemo{
    public static void main(String[] args) {
        new Thread(new Runnable(){// 接口名
            public void run(){// 方法名
                System.out.println("run test()");
            }
        }).start();
//以上代码给Tread类传递了一个匿名的Runnable对象
//重载Runnable接口的run()方法来实现相应逻辑
    }
}

例子1-2 使用lambda表达式改写以上代码

public class  RunnableDemo{
    public static void main(String[] args) {
        new Thread(() -> System.out.println("run test()")).start();
        // 省略接口名和方法名        
    }
} 
在本例中,由于println方法返回的是void,所以对应的表达式同样会返回void,与run方法的类型相匹配

lambda表达式必须匹配接口中单一抽象方法签名的参数类型和返回类型,这被称为与方法签名兼容。所以,lambda表达式属于接口方法的实现,可以将其赋给该接口类型的引用。

比如上述例子,若要将lambda赋给函数式接口引用可以通过以下例子1-3实现:

Runnable runnable =() -> System.out.println("run test()");
new Thread(runnable).start(); 
3.2 有参函数的简写
例子1-4 FilenameFilter的匿名内部类实现

import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;
public class FilenameFilterDemo {
    public static void main(String[] args) {
        File directory = new File("src/test/resources");
        String[] names = directory.list(new FilenameFilter() {    
            public boolean accept(File dir, String name) {
                return name.endsWith(".txt");
            }
        });
        System.out.println(Arrays.asList(names));
    }
}

例1-5 采用lambda表达式改写以上代码

import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;
public class FilenameFilterDemo {
    public static void main(String[] args) {
        File directory = new File("src/test/resources");
        String[] names = directory.list((dir,name)-> name.endsWith(".txt"));
        System.out.println(Arrays.asList(names));
    }
} 
可以看到,代码要简单的多。参数包含在小括号中,但并未声明类型。在编译时,编译器发现list方法传入一个FilenameFilter类型的参数,从而获知其单一抽象方法accept的签名,进而了解accept的参数为File和String,因此兼容的lambda表达式参数必须匹配这些类型。由于accept方法返回的类型是布尔值,所以箭头右边的表达式也必须是返回布尔值。

我们也可以在代码中指定数据类型,如下例1-6所示:

File directory = new File("src/test/resources");
String[] names = directory.list((File dir,String name)-> name.endsWith(".txt")); 
此外,如果lambda表示的实现多于一行,则需要使用大括号和显示返回语句,如例1-7所示:

File directory = new File("src/test/resources");
        
String[] names = directory.list((File dir,String name)-> {
        return name.endsWith(".txt");
    }
); 
这就是lambda代码块,在本例中,虽然代码主体只有一行,但是可以使用大括号将多个语句括起来。注意,不能省略return关键字。

lambda表达式在任何情况下都不能脱离上下文存在,上下文指定了将表达式赋予给哪个函数式接口。lambda表达式既可以是方法的参数,也可以是方法的返回函数,还可以被赋给引用。无论哪种情况,赋值类型必须为函数式接口。
#笔记##Java##读书笔记#
全部评论

相关推荐

09-21 21:14
门头沟学院
否极泰来来来来:和他说:这里不好骂你,我们加个微信聊
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务