- 1 Lambda表达式
- 1.1 体验Lambda表达式
- 1.2 函数式接口
- 1.3 Lambda表达式的使用
- 1.4 Lambda表达式的案例
- 1.5Lambda表达式的省略模式
- 1.6Lambda表达式和匿名内部类区别
- 2 Stream流
- 2.1 Stream的体验
- 2.2 Stream流的三类方法
- 2.3 第一类 : 获取方法
- 2.4 第二类 : 中间方法
- 2.5 第三类 : 终结方法
- 2.6 Stream流中的收集方法
- 3 File类
- 3.1 File类的介绍
- 3.2 构造方法
- 3.3 File类的创建功能
- 3.4 File类的删除功能
- 3.5 File类的判断和获取功能
- 3.6 File类高级获取功能
-
package com.itheima.lambda_demo; public class LambdaDemo { public static void main(String[] args) { // 匿名内部类方式完成 goSwimming(new Swimming() { @Override public void swim() { System.out.println("铁汁 , 我们去游泳吧...."); } }); // lambda表达式的方式完成 goSwimming(() -> System.out.println("铁汁 , 我们去游泳吧....")); } public static void goSwimming(Swimming swimming) { swimming.swim(); } } interface Swimming { public abstract void swim(); } -
lambda表达式可以理解为对匿名内部类的一种简化 , 但是本质是有区别的
-
面向对象思想 :
- 强调的是用对象去完成某些功能
-
函数式编程思想 :
- 强调的是结果 , 而不是怎么去做
- 只有一个抽象方法需要重写的接口,函数式接口。函数式接口是允许有其他的非抽象方法的存在例如静态方法,默认方法,私有方法。
- 为了标识接口是一个函数式接口,可以在接口之上加上一个注解: @FunctionalInterface 以示区别
- 在JDK中 java.util.function 包中的所有接口都是函数式接口。我们之前学习线程时学习的Runnable也是函数式接口
使用前提 :
- 必须存在一个接口
- 接口中有且只有一个抽象方法
格式 : ( 形式参数 ) -> { 代码块 }
- () 形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可
- -> :由英文中画线和大于符号组成,固定写法。代表指向动作
- {} 代码块:是我们具体要做的事情,也就是以前我们写的方法体内容
package com.itheima.lambda_test;
public class LambdaTest1 {
public static void main(String[] args) {
useShowHandler(() -> {
System.out.println("我是一个lambda表达式....");
});
}
public static void useShowHandler(ShowHandler showHandler) {
showHandler.show();
}
}
interface ShowHandler {
public abstract void show();
}
package com.itheima.lambda_test;
public class LambdaTest2 {
public static void main(String[] args) {
useStringHandler((String msg) -> {
System.out.println(msg);
});
}
public static void useStringHandler(StringHandler stringHandler){
stringHandler.printMessage("今天天气不错 , 挺风和日丽的...");
}
}
@FunctionalInterface
interface StringHandler {
public abstract void printMessage(String msg);
}
package com.itheima.lambda_test;
import java.util.Random;
public class LambdaTest3 {
public static void main(String[] args) {
useRandomNumHandler(() -> {
return new Random().nextInt(10) + 1;
});
}
public static void useRandomNumHandler(RandomNumHandler randomNumHandler) {
int number = randomNumHandler.getNumber();
System.out.println(number);
}
}
interface RandomNumHandler {
public abstract int getNumber();
}
package com.itheima.lambda_test;
public class LambdaTest4 {
public static void main(String[] args) {
useCalculator((int a , int b) -> { return a + b;});
}
public static void useCalculator(Calculator calculator) {
int calc = calculator.calc(10, 20);
System.out.println(calc);
}
}
@FunctionalInterface
interface Calculator {
public abstract int calc(int a, int b);
}
1.5Lambda表达式的省略模式
省略规则:
- 参数类型可以省略,但是有多个参数情况下只能省略一个
- 如果参数有且仅有一个,那么小括号可以省略
- 如果代码块只有一条语句,可以省略大括号和分号,甚至return
所需类型不同
- 匿名内部类:可以是接口,也可以是抽象类,还可以是具体类
- Lambda:只能是函数式接口
使用限制不同
- 如果接口中有且仅有一个抽象方法需要重写,可以使用Lambda表达式,也可以使用匿名内部类
- 如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式
实现原理不同
- 匿名内部类:编译之后,产生一个单独的class字节码文件
- Lambda表达式:编译之后,没有一个单独的class字节码文件,对应字节码会在运行时动态生成
package com.itheima.stream_demo;
import java.util.ArrayList;
public class StreamDemo {
public static void main(String[] args) {
// 传统方式完成
ArrayList list = new ArrayList<>();
list.add("张无忌");
list.add("张翠山");
list.add("张三丰");
list.add("谢广坤");
list.add("赵四");
list.add("刘能");
list.add("小沈阳");
list.add("张良");
// 把集合中所有以"张"开头的元素存储到一个新的集合
ArrayList list2 = new ArrayList<>();
for (String s : list) {
if (s.startsWith("张")) {
list2.add(s);
}
}
// 把"张"开头的集合中的长度为3的元素存储到一个新的集合
ArrayList list3 = new ArrayList<>();
for (String s : list2) {
if (s.length() == 3) {
list3.add(s);
}
}
// 遍历list3集合
for (String s : list3) {
System.out.println(s);
}
System.out.println("================================");
// Stream流的方式
list.stream().filter(s -> s.startsWith("张") && s.length() == 3).forEach(s -> System.out.println(s));
}
}
2.2 Stream流的三类方法
- 获取Stream流
- 创建一条流水线,并把数据放到流水线上准备进行操作
- 中间方法
- 流水线上的操作。
- 一次操作完毕之后,还可以继续进行其他操作
- 终结方法
- 一个Stream流只能有一个终结方法
- 是流水线上的最后一个操作
-
单列集合
可以使用Collection接口中的默认方法stream()生成流
default Stream stream() -
双列集合
双列集合不能直接获取 , 需要间接的生成流
可以先通过keySet或者entrySet获取一个Set集合,再获取Stream流 -
数组
Arrays中的静态方法stream生成流 -
把同一种类型多个数据放到stream流中
Stream类中of方法
package com.itheima.stream_demo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
public class StreamDemo2 {
public static void main(String[] args) {
// 单列集合的获取
// method1();
// 双列集合的获取
// method2();
// 数组获取
// method3();
}
private static void method3() {
int[] arr = {1, 2, 3, 4, 5, 6};
Arrays.stream(arr).forEach(s -> System.out.println(s));
}
private static void method2() {
HashMap hm = new HashMap<>();
hm.put("it001", "曹植");
hm.put("it002", "曹丕");
hm.put("it003", "曹熊");
hm.put("it004", "曹冲");
hm.put("it005", "曹昂");
// 获取map集合的健集合 , 在进行输出打印
hm.keySet().stream().forEach(s -> System.out.println(s + "---" + hm.get(s)));
// 获取map集合的entry对象 , 在输出打印
hm.entrySet().stream().forEach(s -> System.out.println(s));
}
private static void method1() {
// 可以使用Collection接口中的默认方法stream()生成流
ArrayList list = new ArrayList<>();
list.add("迪丽热巴");
list.add("古力娜扎");
list.add("马尔扎哈");
list.add("欧阳娜娜");
list.stream().forEach(s -> System.out.println(s));
}
}
2.4 第二类 : 中间方法
package com.itheima.stream_demo;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class StreamDemo3 {
public static void main(String[] args) {
ArrayList list = new ArrayList<>();
list.add("张无忌");
list.add("张翠山");
list.add("张三丰");
list.add("谢广坤");
list.add("赵四");
list.add("刘能");
list.add("小沈阳");
list.add("张良");
list.add("张良");
list.add("张良");
list.add("张良");
// Stream limit(long maxSize):截取指定参数个数的数据
// list.stream().limit(3).forEach(s -> System.out.println(s));
// Stream skip(long n):跳过指定参数个数的数据
// list.stream().skip(3).forEach(s-> System.out.println(s));
// Stream distinct():去除流中重复的元素。依赖(hashCode和equals方法)
// list.stream().distinct().forEach(s->{System.out.println(s);});
}
// // Stream sorted (Comparator super T> comparator) : 将流中元素按照自定义比较器规则排序
private static void method3(ArrayList list) {
list.stream().sorted(new Comparator() {
@Override
public int compare(String o1, String o2) {
return o1.length() - o2.length();
}
}).forEach(s->{
System.out.println(s);
});
}
// Stream sorted () : 将流中元素按照自然排序的规则排序
private static void method3() {
ArrayList list2 = new ArrayList<>();
list2.add(3);
list2.add(1);
list2.add(2);
list2.stream().sorted().forEach(s->{
System.out.println(s);
});
}
// // static Stream concat(Stream a, Stream b):合并a和b两个流为一个流
private static void method2(ArrayList list) {
ArrayList list2 = new ArrayList<>();
list2.add("迪丽热巴");
list2.add("古力娜扎");
list2.add("欧阳娜娜");
list2.add("马尔扎哈");
Stream.concat(list.stream(), list2.stream()).forEach(s -> {
System.out.println(s);
});
}
// Stream filter(Predicate predicate):用于对流中的数据进行过滤
private static void method1(ArrayList list) {
// filter方法会获取流中的每一个数据
// s就代表的是流中的每一个数据
// 如果返回值为true , 那么代表的是数据留下来
// 如果返回值的是false , 那么代表的是数据过滤掉
// list.stream().filter(new Predicate() {
// @Override
// public boolean test(String s) {
// boolean result = s.startsWith("张");
// return result;
// }
// }).forEach(s -> System.out.println(s));
list.stream().filter(s ->
s.startsWith("张")
).forEach(s -> System.out.println(s));
}
}
2.5 第三类 : 终结方法
package com.itheima.stream_demo;
import java.util.ArrayList;
import java.util.function.Consumer;
public class StreamDemo4 {
public static void main(String[] args) {
ArrayList list = new ArrayList<>();
list.add("张无忌");
list.add("张翠山");
list.add("张三丰");
list.add("谢广坤");
// long count():返回此流中的元素数
long count = list.stream().count();
System.out.println(count);
}
// void forEach(Consumer action):对此流的每个元素执行操作
private static void method1(ArrayList list) {
// 把list集合中的元素放在stream流中
// forEach方法会循环遍历流中的数据
// 并循环调用accept方法 , 把数据传给s
// 所以s就代表的是流中的每一个数据
// 我们只要在accept方法中对数据做业务逻辑处理即可
list.stream().forEach(new Consumer() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
System.out.println("=====================");
list.stream().forEach( (String s) -> {
System.out.println(s);
});
System.out.println("=====================");
list.stream().forEach( s -> { System.out.println(s); });
}
}
2.6 Stream流中的收集方法
package com.itheima.stream_demo;
import java.util.ArrayList;
public class StreamDemo5 {
public static void main(String[] args) {
ArrayList list = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
list.add(i);
}
list.stream().filter(num -> num % 2 == 0).forEach(num -> System.out.println(num));
System.out.println("=============");
// 结论:在Stream流中无法直接修改集合,数组中的数据。
System.out.println(list);
}
}
- 结论:在Stream流中无法直接修改集合,数组中的数据
package com.itheima.stream_demo;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class StreamDemo6 {
public static void main(String[] args) {
ArrayList list = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
list.add(i);
}
list.add(10);
list.add(10);
list.add(10);
list.add(10);
list.add(10);
// collect只负责收集流中的数据
// Collectors.toList()会负责在底层创建list集合 ,并把数据添加到集合中 , 返回集合对象
List list2 = list.stream().filter(num -> num % 2 == 0 ).collect(Collectors.toList());
System.out.println(list2);
Set set = list.stream().filter(num -> num % 2 == 0 ).collect(Collectors.toSet());
System.out.println(set);
}
}
package com.itheima.stream_demo;
import java.util.ArrayList;
import java.util.Map;
import java.util.stream.Collectors;
public class StreamDemo7 {
public static void main(String[] args) {
ArrayList list = new ArrayList<>();
list.add("zhangsan,23");
list.add("lisi,24");
list.add("wangwu,25");
// collect 只负责收集数据
// Collectors.toMap负责在底层创建集合对象 , 添加元素
// toMap方法中的s就是代表的是集合中的每一个元素
// 第一个参数 : 如何获取map集合中的键
// 第二个参数 : 如何获取map集合中的值
Map map = list.stream().filter(s -> Integer.parseInt(s.split(",")[1]) > 23).collect(
Collectors.toMap(
(String s) -> {
return s.split(",")[0];
}
,
(String s) -> {
return s.split(",")[1];
}
)
);
System.out.println(map);
}
}
3 File类
3.1 File类的介绍绝对路径:从盘符开始
相对路径:相对当前项目下的路径
- java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作
package com.itheima.file_demo;
import java.io.File;
public class FileDemo1 {
public static void main(String[] args) {
// 1 File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例
File f1 = new File("D:\abc.txt");
System.out.println(f1);
// 2 File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例
File f2 = new File("D:\aaa", "bbb.txt");
System.out.println(f2);
// 3 File(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例
File f3 = new File(new File("D:\aaa"), "bbb.txt");
System.out.println(f3);
}
}
3.3 File类的创建功能
package com.itheima.file_demo;
import java.io.File;
import java.io.IOException;
public class FileDemo2 {
public static void main(String[] args) throws IOException {
File f1 = new File("D:\a.txt");
// 1 public boolean createNewFile() : 创建一个新的空的文件
System.out.println(f1.createNewFile());
File f2 = new File("day10_demo\aaa");
// 2 public boolean mkdir() : 创建一个单级文件夹
System.out.println(f2.mkdir());
File f3 = new File("day10_demo\bbb\ccc");
// 3 public boolean mkdirs() : 创建一个多级文件夹
System.out.println(f3.mkdirs());
}
}
3.4 File类的删除功能
package com.itheima.file_demo;
import java.io.File;
import java.io.IOException;
public class FileDemo3 {
public static void main(String[] args) throws IOException {
File f1 = new File("D:\a.txt");
// 1 public boolean createNewFile() : 创建一个新的空的文件
System.out.println(f1.delete());
File f2 = new File("day10_demo\aaa");
// 2 public boolean mkdir() : 创建一个单级文件夹
System.out.println(f2.delete());
File f3 = new File("day10_demo\bbb");
// 3 public boolean mkdirs() : 创建一个多级文件夹
System.out.println(f3.delete());
}
}
3.5 File类的判断和获取功能
package com.itheima.file_demo;
import java.io.File;
public class FileDemo4 {
public static void main(String[] args) {
File f1 = new File("day10_demo\aaa");
File f2 = new File("day10_demo\a.txt");
// public boolean isDirectory() 测试此抽象路径名表示的File是否为目录
System.out.println(f1.isDirectory());
System.out.println(f2.isDirectory());
// public boolean isFile() 测试此抽象路径名表示的File是否为文件
System.out.println(f1.isFile());
System.out.println(f2.isFile());
// public boolean exists() 测试此抽象路径名表示的File是否存在
System.out.println(f1.exists());
// public String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串
System.out.println(f1.getAbsolutePath());
// public String getPath() 将此抽象路径名转换为路径名字符串
System.out.println(f1.getPath());
// public String getName() 返回由此抽象路径名表示的文件或目录的名称
System.out.println(f2.getName());
}
}
3.6 File类高级获取功能
package com.itheima.file_demo;
import java.io.File;
public class FileDemo5 {
public static void main(String[] args) {
File file = new File("day10_demo\bbb\ccc");
// 返回此抽象路径名表示的目录中的文件和目录的File对象数组
File[] files = file.listFiles();
// 遍历File类的数组
for (File f : files) {
// 拿到每一个文件的文字
System.out.println(f.getName());
}
}
}
练习 :
package com.itheima.file_demo;
import java.io.File;
import java.util.HashMap;
public class FileTest2 {
public static void main(String[] args) {
File file = new File("day10_demo\统计文件个数文件夹");
getFileCount(file);
}
public static void getFileCount(File f) {
HashMap hm = new HashMap<>();
// 是文件夹在获取所有的子文件
if (f.isDirectory()) {
File[] files = f.listFiles();
// 遍历数组
for (File file : files) {
String fileName = file.getName();
String name = fileName.split("\.")[1];
if (hm.containsKey(name)) {
hm.put(name, hm.get(name));
} else {
hm.put(name, 1);
}
}
}
System.out.println(hm);
}
}



