以下是本次笔记目录结构
一.Lambda表达式的由来
Lambda表达式是一个JDK8开始的一个新语法,作用是简化代码,省略了面向对象中类和方法的书写。
二.Lambda表达式的标准格式
(参数类型 参数名,参数类型 参数名,...) -> { 代码语句 }
- 小括号内的语法与传统方法参数列表一致:无参数则留空;多个参数则用逗号分隔。
->
是新引入的语法格式,代表指向动作。- 大括号内的语法与传统方法体要求基本一致。
三.Lambda表达式的使用条件
Lambda表达式的使用条件: 接口中有且仅有一个抽象方法的接口,才可以使用Lambda表达式,接口内可以有默认方法
1.接口中只有一个抽象方法的接口,叫做函数式接口
2.如果是函数式接口,那么就可以使用 @FunctionalInterface注解来标识。
四.Lambda表达式的省略规则
在Lambda标准格式的基础上,使用省略写法的规则为:
- 小括号内参数的类型可以省略;
- 如果小括号内有且仅有一个参数,则小括号可以省略;
- 如果大括号内有且仅有一条语句,则无论是否有返回值,都可以省略大括号、return关键字及语句分号。
五.Lambda表达式标准格式代码,以及省略之后的代码如下所示
标准格式代码:
package Lambda表达式;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Test2 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(200);
list.add(300);
list.add(854);
list.add(150);
list.add(400);
System.out.println("排序前:"+list);
/*Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});未使用Lambda表达式排序前(倒序)*/
Collections.sort(list,(Integer o1,Integer o2)->{
return o1-o2;
});//使用Lambda表达式排序后(正序)
System.out.println("排序后:"+list);
}
}
省略之后的代码:
public class Demo_比较器演示 {
public static void main(String[] args) {
//比较器
ArrayList<Integer> list = new ArrayList<>();
//添加元素
list.add(324);
list.add(123);
list.add(67);
list.add(987);
list.add(5);
System.out.println(list);
//Lambda表达式
Collections.sort(list, ( o1, o2)-> o2 - o1);
//打印集合
System.out.println(list);
}
}
😘
六. Stream流
1.终结方法
- 返回值类型不再是
Stream
接口自身类型的方法,因此不再支持类似StringBuilder
那样的链式调用。本小节中,终结方法包括count
和forEach
方法。
2.非终结方法
- (延迟方法):返回值类型仍然是
Stream
接口自身类型的方法,因此支持链式调用。(除了终结方法外,其余方法均为非终结方法。)
方法名 | 方法作用 | 方法种类 | 是否支持链式调用 |
---|---|---|---|
count | 统计个数 | 终结 | 否 |
forEach | 逐一处理 | 终结 | 否 |
filter | 过滤 | 函数拼接 | 是 |
limit | 取用前几个 | 函数拼接 | 是 |
skip | 跳过前几个 | 函数拼接 | 是 |
map | 映射 | 函数拼接 | 是 |
concat | 组合 | 函数拼接 | 是 |
Lambda与Stream流综合案例
package Stream流的获取.Stream流的综合案例;
import java.util.ArrayList;
import java.util.Collections;
import java.util.stream.Stream;
public class Test {
public static void main(String[] args) {
//现在有两个`ArrayList`集合存储队伍当中的多个成员姓名,要求使用Stream流,依次进行以下若干操作步骤:
ArrayList<String> list1 = new ArrayList<>();
Collections.addAll(list1,"张三丰","张无忌","灭绝师太","周芷若","殷素素");
ArrayList<String> list2 = new ArrayList<>();
Collections.addAll(list2,"刘亦菲","古天乐","胡歌","王宝强","娄艺潇","张艺兴","张类","张明");
//1. 第一个队伍只要名字为3个字的成员姓名;
/* list1.stream().filter((String name)->{
return name.length()==3;
}).forEach((String name1)->{
System.out.println(name1);
});*/
//2. 第一个队伍筛选之后只要前3个人;
/* list1.stream().filter((String name)->{
return name.length()==3;//筛选出来名字为3个字的成员
}).limit(3).forEach((String name1)->{//limit限制为3。
System.out.println(name1);
});*/
//3. 第二个队伍只要姓张的成员姓名;
/* list2.stream().filter((String name)->{
return name.startsWith("张");
}).forEach((String name)->{
System.out.println(name);
});*/
//4. 第二个队伍筛选之后不要前2个人;
/* list2.stream().filter((String name)->{
return name.startsWith("张");
}).skip(2).forEach((String name)->{
System.out.println(name);
});*/
//5. 将两个队伍合并为一个队伍;
Stream<String> first = list1.stream();
Stream<String> second = list2.stream();
Stream<String> concat = Stream.concat(first, second);
//6. 根据姓名创建`Person`对象;
concat.map((String name)->{
return new Person(name);
}).forEach((Person person)->{
System.out.println(person);
});
//7. 打印整个队伍的Person对象信息。
}
}
3.如何接流?
集合:
- Stream流中提供了一个方法,可以把流中的数据收集到单列集合中
- <R,A> R collect(Collector<? super T,A,R> collector): 把流中的数据收集到单列集合中
- 参数Collector<? super T,A,R>: 决定把流中的元素收集到哪个集合中
- 返回值类型是R,也就是说R指定为什么类型,就是收集到什么类型的集合
- 参数Collector如何得到? 使用java.util.stream.Collectors工具类中的静态方法:
- public static Collector<T, ?, List> toList():转换为List集合。
- public static Collector<T, ?, Set> toSet():转换为Set集合。
数组:
Stream提供toArray
方法来将结果放到一个数组中,返回值类型是Object[]的:
4.总结
- 能够说出线程6个状态的名称
新建 创建线程对象时
可运行 调用start()方法时
锁阻塞 没有获取到锁对象
无限等待 使用锁对象调用wait()方法时
计时等待 调用sleep(时间)方法时\调用wait(时间)方法时
被终止 run方法正常运行结束\run方法没有捕获处理异常结束
线程状态之间的切换
- 能够理解等待唤醒案例
- 实现等待唤醒机制程序:
- 必须使用锁对象调用wait方法,让当前线程进入无限等待状态
- 必须使用锁对象调用notify\notifyAll方法唤醒等待线程
- 调用wait\notfiy\notfiyAll方法的锁对象必须一致
- 分析的等待唤醒机制程序:
- 线程的调度依然是抢占式调度
- 线程进入无限等待状态,就不会霸占cpu和锁对象(释放),也不会抢占cpu和锁对象
- 如果是在同步锁中\Lock锁中,调用sleep()方法进入计时等待,不会释放cpu和锁对象(依然占用)
- 能够掌握Lambda表达式的标准格式与省略格式
作用: 就是用来简化代码的,不用去定义类\方法\对象等
格式:
(类型 变量名,类型变量名,...)->{代码...}
格式解释:
1.小括号中的内容和函数式接口中抽象方法的形参列表一致
2.大括号中的内容其实就是以前重写函数式接口抽象方法的方法体
前提条件:
当且仅当接口是函数式接口的,才可以使用Lambda表达式
函数式接口:接口中有且仅有一个抽象方法的接口就是函数式接口,可以使用@FunctionalInterface注解来标识
使用步骤:
1.分析接口是否是函数式接口
2.如果是函数式接口,就写()->{}
3.然后填充小括号和大括号中的内容
省略规则:
1.小扩号中的类型可以省略
2.小括号中有且仅有一个参数,那么小括号也可以省略
3.大括号中有且仅有一条语句,那么大括号,分号,return都可以省略(一起)
表现形式:
变量形式
参数形式
返回值形式
- 能够通过集合、映射或数组方式获取流
单列集合: Collection的stream方法
根据List集合获取流
根据Set集合获取流
映射(双列集合): Collection的Stream方法
根据键获取流
根据值获取流
根据键值对对象获取流
数组: Stream的of(T... args)方法
- 能够掌握常用的流操作
终结方法: forEach,count
延迟方法:
filter:过滤
limit: 取前几个
skip: 跳过
map: 映射
concat: 组合\合并流
- 能够将流中的内容收集到集合和数组中
收集到集合:
List集合: Stream流对象.collect(Collectors.toList())方法
Set集合: Stream流对象.collect(Collectors.toSet())方法
收集到数组:
Stream流对象.toArray();