函数式编程思想
强调的是***做什么,而不是以什么样的方式来做,它忽略了面向对象的复杂语法,只要能够获取到结果,谁去做的,怎么做的,都不重要,重要的是结果,不重视过程***。
冗余的Runnable代码
传统的写法
public class Demo01Runnable {
public static void main(String[] args) {
// 匿名内部类的方式
new Thread(new Runnable() {
@Override
public void run(){
System.out.println("开启了一个新的线程任务");
}
}).start();// 启动新线程
}
}
代码分析:
对于Runnable的匿名内部类用法,可以分析出一下内容:
- Thread类需要Runnable接口作为参数,其中抽象方法run用来指定线程任务内容的核心。
- 为了指定run方法的方法体,不得不需要Runnable接口的实现类
- 为了省去定义一个RunnableImpl实现类的麻烦,不得不使用匿名内部类。
- 必须重写抽象方法run方法,所以方法的名称、方法的参数、方法的返回值不得不在写一遍,且不能写错。
- 从这里面可以,只有方法体才是线程任务的关键性内容
编程思想的转换
做什么,而不是怎么做
我们真正希望做的事情是:将run方法体内的代码传递给Thread类知晓能够加载到即可。
传递一段代码—这是我们真正的目的。
我们需要将程序关注的重点从***怎么做***回归到***做什么***的本质上,过程与形式并不重要。
2014年3月Oracle官方所发布的Java 8(JDK1.8)中,加入了***Lambda表达式***
体验Lambda表达式的更优写法
Java 8的新特性,优化刚才的代码
public class Demo01Runnable {
public static void main(String[] args) {
// 使用Lambda表达式的方式
new Thread(() -> {
System.out.println("开启了一个新的线程任务");
}
).start();// 启动新线程
}
}
从上面的代码可以看出:没有创建接口实现类对象的操作,也不再有抽象方法覆盖重写的操作,只写了线程任务的内容。
从上面的代码能狗推导出Lambda的语法:
() -> System.out.println("开启了一个新的线程任务")
- 前面的一对小括号即run方法,参数为无,里面是空的,此时需要任何的条件
- 中间的一个箭头代表将前面的参数传递给后面的代码
- 后面的输出语句即业务逻辑代码(线程任务内容)
Lambda的标准格式
格式由三个部分组成:
- 一些参数
- 一个箭头
- 一段代码
Lambda表达式的标准格式:
(参数类型1 参数名称1,参数类型2 参数名称2,....) -> {代码语句}
格式说明:
- 小括号内的语法与传统的方法参数列表一致,无参数就留空,多个参数则用逗号隔开
- ->是新引入的语法格式,代表指向的动作
- 大括号内的语法与传统方法体要求基本一致。
练习:定义一个厨子接口,该接口内内置了一个做饭的方法(抽象的方法),且无参数,无返回值,使用Lambda表达式,最后打印输出“我今天吃的是红烧茄子,吃的好开心”。(无参无返回)
练习2:使用数组存储多个学生对象,对数组中的学生对象使用Arrays的sort方法通过年龄进行升序排序。使用Lambda表达式来实现以上需求。(有参无返回)
练习3:给定一个计算器接口,内置了一个抽象方法计算的方法,可以将两个double类型的数字相加得到和值。使用Lambda表达式来实现以上需求。(有参有返回)
代码示例:
Lambda省略格式
可推导即可省略
Lambda强调的是“做什么”,而不是“怎么做”,所以凡是可以根据上下文推导得知的信息,都可以省略。比如:
invokeSum(3.14, 3.15, (double d1,double d2) -> {
return d1 + d2;
});
// 省略格式表达
invokeSum(3.14,3.15,(d1,d2) -> d1 + d2);
省略的规则:
在Lambda标准格式的表达式的基础上,使用省略写法的规则是:
- 小括号内参数的类型可以省略。
- 如果小括号内有且仅有一个参数,则小括号也可以省略
- 如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号、return关键字和语句的分号。
Lambda的使用前提
Lambda的语法非常的简洁,使用非常的简单,但是有以下注意事项:
-
使用Lambda必须具有接口,且要求接口中有且仅有一个抽象方法
无论JDK内置的Runnable、Comparator接口还是自定义的接口,只有当接口中的抽象方法存在且唯一,才可以使用Lambda
-
使用Lambda必须具有***上下文推断***。
也就是方法的参数或者局部变量类型必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例。
备注:有且仅有一个抽象方法的接口,称为函数式接口
File类
##### 概述
java.io.File
类是文件和目录路径名的抽象表示。主要用于文件和目录的创建、查找、删除等操作。
Java把电脑中的文件和文件夹(目录)封装为了一个File类,我们可以使用File类对文件和文件夹进行操作。
可以使用File类的方法:
- 创建一个文件、文件夹
- 删除一个文件、文件夹
- 获取一个文件、文件夹
- 判断文件、文件夹是否存在
- 对文件夹进行遍历
- 获取文件的大小
File类是一个与系统无关的类,任何的操作系统都可以使用这个类中的方法。
构造方法
- public File(String pathname):通过将给定路径名字符串转换为抽象路径名来创建一个新
File
实例。 - public File(String parent,String child):根据 parent 路径名字符串和 child 路径名字符串创建一个新
File
实例。 - public File(File parent,String child):根据 parent 抽象路径名和 child 路径名字符串创建一个新
File
实例。
代码示例:
常用API方法
- 获取功能的方法
- 判断功能的方法
- 路径功能的方法
- 创建删除功能的方法
- 目录遍历功能的方法
获取功能的方法
- public String getAbsolutePath():返回此抽象路径名的绝对路径名字符串。
- public String getPath():将此File转换为路径名字符串
- public String getName():返回由此File表示的文件或目录的名称。
- public long length():返回此File表示的文件的长度。
判断功能的方法
- public boolean exists():判断File表示的文件或者文件夹是否实际存在
- public boolean isDirectory():判断此File表示的文件夹是否存在
- public boolean isFile():判断此File表示的文件是否存在
创建和删除文件的方法
- public boolean createNewFile():当且仅当具有该名称的文件不存在时,创建一个新的空的文件,返回值是true
- public boolean delete():删除由此File表示的文件或者目录
- public boolean mkdir():创建由此File表示的文件夹
- public boolean mkdirs():创建由此File表示的文件夹,包括任何必须但是又不存在的父目录。
目录的遍历
- public String[] list():返回一个String数组,表示该File目录中的所有的子目录或者子文件。
- public File[] listFile():返回一个File数组,表示该File目录中的所有的子目录或者子文件。