肖sir_Java 8 新特性__21

1.1 Lambda 表达式
Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
语法
1,(parameters) -> expression
2,(parameters) ->{ statements; }
lambda表达式的重要特征:
可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
可选的参数圆括号:一个参数无需定义圆括号,但多个参数或无参数需要定义圆括号。
可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。
 
1.2 Lambda 表达式
函数式接口:如果一个接口中只有一个抽象方法(可以包含多个默认方法或多个
static 方法),那么该接口就是函数式接口。在使用Lambda 表达式时必须是函数式
接口。如果一个接口中有两个抽象方法则不可以使用Lambda表达式。
比如:
public class Lesson21 {
public static void main(String[] args) {
LambdaDemo1 demo1 = () -> System.out.println(5);
demo1.demo();
}
}
public interface LambdaDemo1 {
void demo();
 
1.3 Lambda 表达式
Lambda 表达式实例:
// 1. 不需要参数,返回值为 5
() -> 5
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
 
}
说明:Lambda表达式对应的函数式接口只能包含一个抽象方法,包含多个则报错
 
1.4 Lambda 表达式
使用 Lambda 表达式需要注意以下两点:
Lambda 表达式主要用来定义行内执行的方法类型接口,
Lambda 表达式免去了使用匿名方法的麻烦,并且给予Java简单但是强大的函数化的编程能力。
变量作用域
lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。
lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)
在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。
 
1.5 Lambda 表达式
练习题:
1.请在测试类main方法中完成以下需求
已知有Integer[] arr = {-12345, 9999, 520, 0,-38,-7758520,941213}
a)使用lambda表达式创建Predicate对象p1,p1能判断整数是否是自然数(大于等于0)
b)使用lambda表达式创建Predicate对象p2,p2能判断整数的绝对值是否大于100
c)使用lambda表达式创建Predicate对象p3,p3能判断整数是否是偶数
遍历arr,仅利用已创建的Predicate对象(不使用任何逻辑运算符),完成以下需求
i.打印自然数的个数
ii.打印负整数的个数
iii.打印绝对值大于100的偶数的个数
iv.打印是负整数或偶数的数的个数
2.1 Stream API
什么是 Stream?
Stream(流)是一个来自数据源的元素队列并支持聚合操作,元素是特定类型的对
象,形成一个队列。Java中的Stream并不会存储元素,而是按需计算。
Stream 就如同一个迭代器(Iterator),单向,不可往复,数据只能遍历一次,遍历过一次后即用尽了,就好比流水从面前流过,一去不复返。
流的操作可以分为两种类型:
中间方法:中间操作允许流保持打开状态,并允许直接调用后续方法。
末端方法:末端方法是对流的最终操作。当对某个 Stream 执行末端方法后,该流将会被“消耗”且不再可用。
 
2.2 Stream API
流的常用创建方法:
1,使用Collection下的 stream() 和 parallelStream() 方法,例如:
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream(); //获取一个顺序流
Stream<String> parallelStream = list.parallelStream(); //获取一个并行流
2,使用Arrays 中的 stream() 方法,将数组转成流,例如:
Integer[] nums = new Integer[10];
Stream<Integer> stream = Arrays.stream(nums);
2.3 Stream API
Stream 常用的中间方法

 

 

2.4 Stream API
Stream 常用的末端方法:

 

 

2.5 Stream API
forEach
Stream 提供了新的方法 'forEach' 来迭代流中的每个数据。使用 forEach 输出了10个随机数:
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
map
map 方法用于映射每个元素到对应的结果,使用 map 输出了元素对应的平方数:
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
// 获取对应的平方数
List<Integer> sList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
filter
filter 方法用于通过设置的条件过滤出元素。使用 filter 方法过滤出空字符串:
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 获取空字符串的数量
long count = strings.stream().filter(string -> string.isEmpty()).count();
 
2.6 Stream API
imit
limit 方法用于获取指定数量的流。 使用 limit 方法打印出 10 条数据:
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
sorted
sorted 方法用于对流进行排序。使用 sorted 方法对输出的 10 个随机数进行排序:
Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);
并行(parallel)程序
parallelStream 是流并行处理程序的代替方法。使用 parallelStream 来输出空字符串的数量:
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 获取空字符串的数量
int count = strings.parallelStream().filter(string -> string.isEmpty()).count();
 
2.7 Stream API
Collectors
Collectors类实现了很多归约操作,例如将流转换成集合和聚合元素。
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filter = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
System.out.println("筛选列表: " + filter );
String mString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("合并字符串: " + mString );
统计
另外,一些产生统计结果的收集器也非常有用。
它们主要用于int、double、long等基本类型上,它们可以用来产生类似如下的统计结果。
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("列表中最大的数 : " + stats.getMax());
System.out.println("列表中最小的数 : " + stats.getMin());
System.out.println("所有数之和 : " + stats.getSum());
System.out.println("平均数 : " + stats.getAverage());
 
2.8 Stream API
练习题:
1.已知学生成绩如下
姓名 成绩
岑小村 59
谷天洛 82
渣渣辉 98
蓝小月 65
皮几万 70
a,以学生姓名为key成绩为value创建Map集合,使用stream求学生的平均成绩。
b,使用stream将Map<String,Integer>中value存到ArrayList中。
 
3.1 默认方法
Java 8 新增了接口的默认方法。
简单说,默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法。
我们只需在方法名前面加个 default 关键字即可实现默认方法。
语法
默认方法语法格式如下:
public interface Vehicle {
default void print(){
System.out.println("我是一辆车!");
}
}
 
3.2 默认方法
多个默认方法
一个接口有默认方法,一个类实现了多个接口,且这些接口有相同的默认方法
例如:
public interface Vehicle {
default void print(){
System.out.println("我是一辆车!");
}
}
public interface FourWheeler {
default void print(){
System.out.println("我是一辆四轮车!");
}
}
 
3.3 默认方法
多个默认方法
第一个解决方案是创建自己的默认方法,来覆盖重写接口的默认方法:
public class Car implements Vehicle, FourWheeler {
default void print(){
System.out.println("我是一辆四轮汽车!");
}
}
第二种解决方案可以使用 super 来调用指定接口的默认方法:
public class Car implements Vehicle, FourWheeler {
public void print(){
Vehicle.super.print();
}
}
 
3.4 静态默认方法
Java 8 的另一个特性是接口可以声明(并且可以提供实现)静态方法。例如:
public interface Vehicle {
default void print(){
System.out.println("我是一辆车!");
}
// 静态方法
static void blowHorn(){
System.out.println("按喇叭!!!");
}
}1
 
 
 
 
 
 
posted @ 2022-10-01 14:06  xiaolehua  阅读(21)  评论(0编辑  收藏  举报