记录:292
场景:Stream流操作基本步骤一般归纳为:Stream流的创建、Stream流的中间操作、Stream流的终止操作。以数据源List为例,先把List
版本:
- JDK 1.8
- Spring Boot 2.6.3
一、基础
1.函数式接口
(1)使用@FunctionalInterface注解标记的接口,接口中有且只有一个抽象方法。
(2)接口中的默认方法、静态方法等不计入抽象方法。
(3)JDK 1.8及其后续版本。
(4)函数入参中使用函数式接口,本质就是重写函数式接口中的抽象方法。
(5)函数入参中有函数式接口定义的参数是,使用Lambda表达式或者匿名类实现抽象方法是常用的方式。
(6)Stream流式编程中的API中大量使用了函数式接口作为入参。
2.Lambda 表达式
Lambda表达式,是Java 8 发布的重要特性。
Lambda允许把函数作为一个方法的参数,即函数作为参数传递进方法中。
Lambda表达式是代码变得更加简洁和紧凑。
Lambda表达式语法规则:
- #方式一:
- (parameters) -> expression
- #方式二:
- (parameters) ->{ expression; }
3.对 super T>和 extends R>理解
对 super T>和 extends R>理解,就是对泛型的理解。
3.1 概念理解
super T>:表示?匹配的类型都是T的父类,包括T本身。
extends R>:表示?匹配的类型都是类型R的子类,包括R本身
3.2 使用List协助理解
3.2.1 List<? super T>
List super T> list:表示集合中存放的都是T的父类(包括T本身)。
针对变量List super T> list。
(1)对List做添加(add(T))操作,必须使用T或者T的子类添加到list中。
(2)对List做遍历查询操作,必须使用T父类去遍历list,取出元素。
小结:拿到一个变量使用? super T修饰时,应该是对该变量做添加操作,不做查询操作。这种方式修饰叫做put原则。
3.2.2 List extends R>
List extends R> list:表示集合中存放的都是R的子类(包括R本身)。
针对变量List extends R> list。
(1)对List做添加(add(R))操作,必须使用R或者R的子类添加到list中。
(2)对List做遍历查询操作,必须使用R遍历list,取出元素.
小结:拿到一个变量使用? extends R修饰时,应该是对该变量做查询或取元素操作,不做添加操作。这种方式修饰叫做get原则。
二、Stream基础
1.Stream接口位置
(1)在jdk中,java.util.stream包下,存放的都是Stream相关的接口和实现类。
(2)在jdk中,Stream路径:java.util.stream.Stream。
Stream是interface类型,继承BaseStream和AutoCloseable接口。
BaseStream路径:java.util.stream.BaseStream。
AutoCloseable路径:java.lang.AutoCloseable
2.Stream理解
Stream,基于lambda表达式,是对集合对象功能的增强,以一种声明的方式处理数据。可以执行过滤、映射数据、查找、聚合等操作。
3.Stream操作
Stream的操作,一般归纳为3个步骤。
3.1 Stream流的创建
要操作流,需获取流,可以从集合、数组、或者Stream的静态方法创建流。
比如:
(1)java.util.Collection的Stream
(2)java.util.Arrays的stream方法,可以把数组转换为Stream。而且Arrays工具类重载了各种型式的stream方法,可以满足大部分从数组转换为Stream的需求。
(3)Stream的静态方法创建Stream流,比如of方法。
3.2 Stream流的中间操作
操作Stream流,比如filter过滤操作、map一个流转换为另一个流程、sorted排序、distinct去重等操作。
3.3 Stream流的终止操作
Stream流的终止操作后,可以从流中生成结果,其结果可以是任何不是流的值。比如forEach遍历结果、collect转换为其它型类型式。
4.stream包的几个Stream接口
java.util.stream包的几个Stream接口。Stream、IntStream、LongStream、DoubleStream接口都继承BaseStream。
- java.util.stream.BaseStream
- java.util.stream.Stream
- java.util.stream.IntStream
- java.util.stream.LongStream
- java.util.stream.DoubleStream
三、Stream应用
本例根据操作Stream的3个基本步骤,把函数分为3类,在逐个应用。
1.应用Stream流的创建函数
应用Stream流的创建方式,使用这些函数可以从数据源获取Stream流。
1.1 操作场景
操作场景,就是函数功能。
(1)使用List获取Stream流。
(2)使用Map获取Stream流。
(3)使用List获取Stream流。
(4)使用List获取Stream流。
(5)使用Stream.of获取Stream流
(6)使用Stream.Builder获取Stream流。
(7)使用Stream.generate获取Stream流。
(8)使用Stream.iterate获取Stream流。
(9)使用Stream.concat合并两个流。
(10)使用Stream.empty获取空流。
1.2 操作实例
操作实例,就是函数应用。
- /**
- * 1.1使用List获取Stream流
- */
- public static void f1_1() {
- // 1.获取数据(List)
- List
list = getList(); - // 2.获取Stream流(使用List)
- Stream
stream = list.stream(); - // 3.遍历Stream流
- stream.forEach(girlVo -> {
- System.out.println(girlVo.toString());
- });
- }
-
- /**
- * 1.2使用Map获取Stream流
- */
- public static void f1_2() {
- // 1.获取数据(Map)
- Map
map = getMap(); - // 2.获取Stream流(使用Map)
- Stream
> stream = map.entrySet().stream(); - // 3.遍历Stream流
- stream.forEach(girlVo -> System.out.println(girlVo.toString()));
- }
-
- /**
- * 1.3使用List获取Stream流
- */
- public static void f1_3() {
- // 1.获取数据(set)
- Set
list = getSet(); - // 2.获取Stream流(使用set)
- Stream
stream = list.stream(); - // 3.遍历Stream流
- stream.forEach(girlVo -> {
- System.out.println(girlVo.toString());
- });
- }
-
- /**
- * 1.4使用List获取Stream流
- */
- public static void f1_4() {
- // 1.获取数据(数组)
- String[] cityArray = new String[]{"厦门", "杭州", "苏州", "北京"};
- // 2.获取Stream流(使用数组)
- Stream
stream = Arrays.stream(cityArray); - // 3.遍历Stream流
- stream.forEach(System.out::println);
- }
-
- /**
- * 1.5使用Stream.of获取Stream流
- */
- public static void f1_5() {
- // 1.使用Stream.of获取Stream流(单个元素)
- Stream
stream01 = Stream.of("杭州"); - // 2.使用Stream.of获取Stream流
- Stream
stream02 = Stream.of("北京", "杭州", "厦门", "苏州"); - stream02.forEach(System.out::println);
- }
-
- /**
- * 1.6使用Stream.Builder获取Stream流
- */
- public static void f1_6() {
- // 1.创建Builder
- Stream.Builder
- // 2.添加元素
- builder.add("北京");
- builder.add("苏州");
- // 3.创建Stream
- Stream
- // 4.遍历Stream
- stream.forEach(System.out::println);
- }
-
- /**
- * 1.7使用Stream.generate获取Stream流
- */
- public static void f1_7() {
- Stream
stream04 = Stream.generate(Math::random); - stream04.forEach(num -> System.out.println("generate: " + num));
- }
-
- /**
- * 1.8使用Stream.iterate获取Stream流
- */
- public static void f1_8() {
- Stream
stream05 = Stream.iterate(30L, ele -> (ele + 2)); - stream05.forEach(num -> System.out.println("iterate: " + num));
- }
-
- /**
- * 1.9 使用Stream.concat合并两个流
- */
- public static void f1_9() {
- // 1.使用Stream.of获取Stream流
- Stream
stream0401 = Stream.of("北京", "杭州"); - Stream
stream0402 = Stream.of("厦门", "苏州"); - // 2.使用Stream.concat合并两个流
- Stream
stream04 = Stream.concat(stream0401, stream0402); - stream04.forEach(num -> System.out.println("合并流: " + num));
- }
-
- /**
- * 1.10 使用Stream.empty获取空流
- */
- public static void f1_10() {
- // 1.使用Stream.empty获取空流
- Stream
stream01 = Stream.empty(); - }
2.应用Stream流的中间操作函数
应用Stream流的中间操作函数,使用这些函数对Stream流进行操作,操作的结果还是Stream流。
2.1 操作场景
操作场景,就是函数功能。
(1)应用Stream的filter,做过滤筛选操作。
(2)应用Stream的map,把Stream
(3)应用Stream的mapToInt,把Stream
(4)应用Stream的mapToLong,把Stream
(5)应用Stream的mapToDouble,把Stream
(6)应用Stream的flatMap,把List>转换为Stream
(7)应用Stream的flatMapToInt,把List>转换为IntStream。
(8)应用Stream的flatMapToLong,把List>转换为LongStream。
(9)应用Stream的flatMapToDouble,把List>转换为DoubleStream。
(10)应用Stream的distinct去重。
(11)应用Stream的sorted排序。
(12)应用Stream的sorted排序。
(13)应用Stream的peek调试。
(14)应用Stream的limit,限制数量。
(15)应用Stream的skip,跳过指定个数元素。
2.2 操作实例
操作实例,就是函数应用。
- /**
- * 2.1 应用Stream的filter,做过滤筛选操作
- * 案例: 找出B罩杯,年龄最小的女孩.
- */
- public static void f2_1() {
- // 1.获取数据(List)
- List
list = getList(); - // 2.获取Stream流(使用List)
- Stream
stream = list.stream(); - // 3.Stream的filter的使用
- OptionalLong optionalLong = stream.filter(girlVo -> Objects.equals(
- girlVo.getCupSize(), "B"))
- .mapToLong(GirlVo::getAge).min();
- // 4.获取结果
- if (optionalLong.isPresent()) {
- System.out.println("B罩杯,年龄最小的女孩: " + optionalLong.getAsLong());
- }
- }
-
- /**
- * 2.2 应用Stream的map
- * 案例: 把Stream
转换为Stream - */
- public static void f2_2() {
- // 1.获取数据(List)
- List
list = getList(); - // 2.获取Stream流(使用List)
- Stream
stream = list.stream(); - // 3.Stream
转换为Stream - Stream
- Object obj = girlVo.getGirlName();
- return obj;
- });
- // 4.遍历结果
- objStream.forEach(obj -> {
- System.out.println("Girl的名称: " + obj.toString());
- });
- }
-
- /**
- * 2.3 应用Stream的mapToInt
- * 案例: 把Stream
转换为IntStream - */
- public static void f2_3() {
- // 1.获取数据(List)
- List
list = getList(); - // 2.获取Stream流(使用List)
- Stream
stream = list.stream(); - // 3.Stream
转换为IntStream - IntStream intStream = stream.mapToInt(girlVo -> {
- int girlId = Integer.parseInt(girlVo.getGirlId());
- return girlId;
- });
- // 4.遍历结果
- intStream.forEach(girlId -> {
- System.out.println("Girl的ID: " + girlId);
- });
- }
-
- /**
- * 2.4 应用Stream的mapToLong
- * 案例: 把Stream
转换为LongStream - */
- public static void f2_4() {
- // 1.获取数据(List)
- List
list = getList(); - // 2.获取Stream流(使用List)
- Stream
stream = list.stream(); - // 3.Stream
转换为LongStream - LongStream longStream = stream.mapToLong(girlVo -> {
- long girlId = girlVo.getAge();
- return girlId;
- });
- // 4.使用LongStream的average求平均值
- OptionalDouble opt = longStream.average();
- if (opt.isPresent()) {
- System.out.println("Girl的平均年龄: " + opt.getAsDouble());
- }
- }
-
- /**
- * 2.5 应用Stream的mapToDouble
- * 案例: 把Stream
转换为DoubleStream - */
- public static void f2_5() {
- // 1.获取数据(List)
- List
list = getList(); - // 2.获取Stream流(使用List)
- Stream
stream = list.stream(); - // 3.Stream
转换为DoubleStream - DoubleStream doubleStream = stream.mapToDouble(girlVo -> {
- double height = girlVo.getHeight();
- return height;
- });
- // 4.使用DoubleStream的max求最大值
- OptionalDouble opt = doubleStream.max();
- if (opt.isPresent()) {
- System.out.println("身高最高的girl身高: " + opt.getAsDouble());
- }
- }
-
- /**
- * 2.6 应用Stream的flatMap
- * 案例: 把List
>转换为Stream
- */
- public static void f2_6() {
- // 1.获取数据(List
>)
- List
> list = getMultiList();
- // 2.List
>转换为Stream
- Stream
stream = list.stream().flatMap(mapper -> { - return mapper.stream();
- });
- // 3.遍历结果
- stream.forEach(obj -> {
- System.out.println("遍历信息: " + obj.toString());
- });
- }
-
- /**
- * 2.7 应用Stream的flatMapToInt
- * 案例: 把List
>转换为IntStream
- */
- public static void f2_7() {
- // 1.获取数据(List
>)
- List
> list = getMultiList();
- // 2.List
>转换为IntStream
- IntStream stream = list.stream().flatMapToInt(mapper -> {
- Stream
girlStream = mapper.stream(); - return girlStream.mapToInt(girl -> {
- return (int) girl.getAge();
- });
- });
- // 3.遍历结果
- stream.forEach(age -> {
- System.out.println("年龄: " + age);
- });
- }
-
- /**
- * 2.8 应用Stream的flatMapToLong
- * 案例: 把List
>转换为LongStream
- * 相当于: 把List
>循环遍历2次直接在Stream中完成
- */
- public static void f2_8() {
- // 1.获取数据(List
>)
- List
> list = getMultiList();
- // 2.List
>转换为LongStream
- LongStream stream = list.stream().flatMapToLong(mapper -> {
- Stream
girlStream = mapper.stream(); - return girlStream.mapToLong(girl -> Long.parseLong(girl.getGirlId()));
- });
- // 3.遍历结果
- stream.forEach(age -> {
- System.out.println("年龄: " + age);
- });
- }
-
- /**
- * 2.9 应用Stream的flatMapToDouble
- * 案例: 把List
>转换为DoubleStream
- */
- public static void f2_9() {
- // 1.获取数据(List
>)
- List
> list = getMultiList();
- // 2.List
>转换为LongStream
- DoubleStream stream = list.stream().flatMapToDouble(mapper -> {
- Stream
girlStream = mapper.stream(); - // Lambda表达式写法
- return girlStream.mapToDouble(GirlVo::getHeight);
- });
- // 3.遍历结果
- stream.forEach(height -> {
- System.out.println("身高: " + height);
- });
- }
-
- /**
- * 2.10 应用Stream的distinct去重
- * 案例: 应用Stream的distinct去重
- * 原理: 去重根据Object.equals(Object)判断
- * Girl01是从写了equals(Object obj)和 hashCode(),去重效果才会生效
- */
- public static void f2_10() {
- // 1.获取数据(List)
- List
list = getList01(); - // 2.获取Stream流(使用List)
- Stream
stream01 = list.stream(); - // 3.使用distinct去重
- Stream
stream02 = stream01.distinct(); - // 4.遍历结果
- stream02.forEach(Girl01 -> {
- System.out.println("Girl信息: " + Girl01);
- });
- }
-
- /**
- * 2.11 应用Stream的sorted排序
- * 案例: 应用Stream的sorted排序
- */
- public static void f2_11() {
- // 1.获取数据(List)
- List
list = getList(); - // 2.获取Stream流(使用List)
- Stream
stream01 = list.stream(); - // 3.使用sorted排序
- Stream
stream02 = stream01.map(GirlVo::getAge).sorted(); - // 4.遍历结果
- stream02.forEach(girl -> {
- System.out.println("Girl年龄: " + girl);
- });
- }
-
- /**
- * 2.12 应用Stream的sorted排序
- * 案例: 应用Stream的sorted排序
- */
- public static void f2_12() {
- // 1.获取数据(List)
- List
list = getList(); - // 2.获取Stream流(使用List)
- Stream
stream01 = list.stream(); - // 3.使用sorted排序 int compare(T o1, T o2);o1-o2代表正序排序,o2-o1代表倒序排序
- Stream
stream02 = stream01.sorted((girl01, girl02) -> { - return (int) (girl01.getAge() - girl02.getAge());
- });
- // 4.遍历结果
- stream02.forEach(girl -> {
- System.out.println("Girl信息: " + girl);
- });
- }
-
- /**
- * 2.13 应用Stream的peek调试
- * 案例: 应用Stream的peek对流操作中的流水线进行调试
- */
- public static void f2_13() {
- // 1.获取数据(List)
- List
list = getList(); - // 2.应用Stream的peek记录调试过程
- Stream
stream01 = list.stream().peek(girlVo -> { - System.out.println("首次peek: " + girlVo);
- }).filter(girlVo -> girlVo.getAge() > 25)
- .peek(girlVo -> {
- System.out.println("filter后peek: " + girlVo);
- }).sorted((girl01, girl02) -> {
- return (int) (girl01.getAge() - girl02.getAge());
- }).peek(girlVo -> {
- System.out.println("sorted后peek: " + girlVo);
- });
- // 3.遍历结果
- stream01.forEach(girl -> {
- System.out.println("forEach遍历girl信息: " + girl);
- });
- }
-
- /**
- * 2.14 应用Stream的limit,限制数量
- * 案例: 应用Stream的limit,限制数量
- */
- public static void f2_14() {
- // 1.获取数据(List)
- List
list01 = getList(); - // 2.获取Stream流(使用List)
- Stream
stream01 = list01.stream(); - // 3.应用Stream的limit
- List
list0101 = stream01.limit(2).collect(Collectors.toList()); - }
-
- /**
- * 2.15 应用Stream的skip,跳过指定个数元素
- * 案例: 应用Stream的skip,跳过指定个数元素
- */
- public static void f2_15() {
- // 1.获取数据(List)
- List
list02 = getList(); - // 2.获取Stream流(使用List)
- Stream
stream02 = list02.stream(); - // 3.应用Stream的skip
- List
list0201 = stream02.skip(2).collect(Collectors.toList()); - }
3.应用Stream流的终止操作函数
应用Stream流的终止操作函数,使用这些函数对Stream流进行操作后,生成结果不是Stream流了,而是一个期待类型的结果值。
3.1 操作场景
操作场景,就是函数功能。
(1)应用Stream的forEach和forEachOrdered遍历结果。
(2)应用Stream的toArray将流转换为数组。
(3)应用Stream的reduce,做累加操作。
(4)应用Stream的collect,将流转换为集合。
(5)应用Stream的collect,将流转换为连续字符串。
(6)应用Stream的collect,将流转换为List集合。
(7)应用Stream的collect,对流做分组操作,转换为Map
(8)应用Stream的collect,对流做分组操作,转换为Map
(9)应用Stream的min,找到最小值。
(10)应用Stream的max,找到最大值。
(11)应用Stream的count,找到元素个数。
(12)应用Stream的anyMatch,有一个匹配则true。
(13)应用Stream的allMatch,全部匹配则true。
(14)应用Stream的noneMatch,不存在则true。
(15)应用Stream的findFirst,找到第一个元素。
(16)应用Stream的findAny,找到任意一个元素。
3.2 操作实例
操作实例,就是函数应用。
- /**
- * 3.1 应用Stream的forEach遍历结果
- * 案例: 应用Stream的forEach和forEachOrdered
- */
- public static void f3_1() {
- // 1.1 获取数据(List)
- List
list03 = getList(); - // 1.2 获取Stream流(使用List)
- Stream
stream03 = list03.stream(); - // 1.3 使用forEach遍历结果
- stream03.forEach(girlVo -> System.out.println("girl信息: " + girlVo));
- // 2.1 获取数据(List)
- List
list04 = getList(); - // 2.2 获取Stream流(使用List)
- Stream
stream04 = list04.stream(); - // 2.3 使用forEachOrdered遍历结果
- stream04.forEachOrdered(girlVo -> System.out.println("girl信息Ordered: " + girlVo));
- }
-
- /**
- * 3.2 应用Stream的toArray
- * 案例: 应用Stream的toArray将流转换为数组
- */
- public static void f3_2() {
- // 1.1 获取数据(List)
- List
list05 = getList(); - // 1.2 获取Stream流(使用List)
- Stream
stream05 = list05.stream(); - // 1.3 应用toArray将Stream流转换为数组
- Object[] objs = stream05.toArray();
- // 2.1 获取数据(List)
- List
list06 = getList(); - // 2.2 获取Stream流(使用List)
- Stream
stream06 = list06.stream(); - // 2.3 应用toArray将Stream流转换为数组
- Object[] objs2 = stream06.toArray(GirlVo[]::new);
- }
-
- /**
- * 3.3 应用Stream的reduce
- * 案例: 应用Stream的reduce,做累加操作
- */
- public static void f3_3() {
- // 1.1 获取数据(List)
- List
list01 = getList(); - // 1.2.获取Stream流(使用List)
- LongStream stream01 = list01.stream().mapToLong(GirlVo::getAge);
- // 1.3 应用reduce求和操作
- OptionalLong opt01 = stream01.reduce((a, b) -> a + b);
- if (opt01.isPresent()) {
- System.out.println("输出值: " + opt01.getAsLong());
- }
- // 2.1 获取数据(List)
- List
list02 = getList(); - // 2.2.获取Stream流(使用List)
- LongStream stream02 = list02.stream().mapToLong(GirlVo::getAge);
- // 2.3 应用reduce求和操作
- long opt02 = stream02.reduce(100, (a, b) -> a + b);
- System.out.println("输出值: " + opt02);
- // 3.1 获取Stream流(Stream.of)
- Stream
stream = Stream.of(100, 200, 300, 400); - // 3.2 应用reduce求和操作
- Integer result = stream.reduce(0, Integer::sum, Integer::sum);
- System.out.println("result" + result);
- }
-
- /**
- * 3.4 应用Stream的collect
- * 案例: 应用Stream的collect,将流转换为集合
- */
- public static void f3_4() {
- // 1.获取Stream流(Stream.of)
- Stream
stringStream0101 = Stream.of("北京", "杭州", "厦门", "苏州"); - // 2.应用Stream的collect,将流转换为集合
- List
asList0101 = stringStream0101.collect(ArrayList::new, ArrayList::add, - ArrayList::addAll);
- System.out.println("asList0101: " + asList0101);
- }
-
- /**
- * 3.5 应用Stream的collect
- * 案例: 应用Stream的collect,将流转换为连续字符串
- */
- public static void f3_5() {
- // 1.获取Stream流(Stream.of)
- Stream
stringStream02 = Stream.of("北京,", "杭州,", "厦门,", "苏州,", "是不错的城市."); - // 2.应用Stream的collect,将流转换为连续字符串
- String concat = stringStream02.collect(StringBuilder::new, StringBuilder::append,
- StringBuilder::append).toString();
- System.out.println("concat: " + concat);
- }
-
- /**
- * 3.6 应用Stream的collect
- * 案例: 应用Stream的collect,将流转换为List集合
- */
- public static void f3_6() {
- // 1.获取Stream流(Stream.of)
- Stream
stringStream0201 = Stream.of("北京", "杭州", "郑州", "厦门", "苏州"); - // 2.应用Stream的collect,将流转换为List
- List
asList0201 = stringStream0201.collect(Collectors.toList()); - System.out.println("asList0201: " + asList0201);
- }
-
- /**
- * 3.7 应用Stream的collect
- * 案例: 应用Stream的collect,对流做分组操作,转换为Map
> - */
- public static void f3_7() {
- // 1.获取Stream流(Stream.of)
- Stream
girlStream0201 = getList().stream(); - // 2.应用Stream的collect,将流分组转换为Map
> - Map
> girlByCupSize = girlStream0201.collect(Collectors.groupingBy(GirlVo::getCupSize)); - System.out.println("girlByCupSize: " + girlByCupSize);
- }
-
- /**
- * 3.8 应用Stream的collect
- * 案例: 应用Stream的collect,对流做分组操作,转换为Map
>> - */
- public static void f3_8() {
- // 1.获取Stream流(使用List)
- Stream
girlStream0202 = getList().stream(); - // 2.应用Stream的collect,对流做分组操作,转换为Map
>> - Map
>> girlByCupSizeAndAge - = girlStream0202.collect(Collectors.groupingBy(GirlVo::getCupSize,
- Collectors.groupingBy(GirlVo::getAge)));
- System.out.println("peopleByCupSizeAndAge: " + girlByCupSizeAndAge);
- }
-
- /**
- * 3.9 应用Stream的min
- * 案例: 应用Stream的min,找到最小值
- */
- public static void f3_9() {
- // 1.获取Stream流(Stream.of)
- Stream
stream01 = Stream.of(100L, 200L, 300L); - // 2.应用Stream的min,求最小值
- Optional
opt01 = stream01.min((o1, o2) -> (int) (o1 - o2)); - // 3.获取结果
- if (opt01.isPresent()) {
- System.out.println("opt01: " + opt01);
- }
- }
-
- /**
- * 3.10 应用Stream的max
- * 案例: 应用Stream的max,找到最大值
- */
- public static void f3_10() {
- // 1.获取Stream流(Stream.of)
- Stream
stream02 = Stream.of(100L, 200L, 300L); - // 2.应用Stream的max,求最小值
- Optional
opt02 = stream02.max((o1, o2) -> (int) (o1 - o2)); - // 3.获取结果
- if (opt02.isPresent()) {
- System.out.println("opt02: " + opt02);
- }
- }
-
- /**
- * 3.11 应用Stream的count
- * 案例: 应用Stream的count,找到元素个数
- */
- public static void f3_11() {
- // 1.获取Stream流(Stream.of)
- Stream
stream03 = Stream.of(100L, 200L, 300L); - // 2.应用Stream的count,求元素个数
- long opt03 = stream03.count();
- // 3.打印结果
- System.out.println("opt03: " + opt03);
- }
-
- /**
- * 3.12 应用Stream的anyMatch
- * 案例: 应用Stream的anyMatch,有一个匹配则true
- */
- public static void f3_12() {
- // 1.获取Stream流(使用List)
- Stream
girlStream01 = getList().stream(); - // 2.应用Stream的anyMatch,有一个匹配则true
- boolean result01 = girlStream01.anyMatch(girl -> Objects.equals(girl.getCupSize(), "B"));
- // 3.打印结果
- System.out.println("是否有B罩杯: " + result01);
- }
-
- /**
- * 3.13 应用Stream的allMatch
- * 案例: 应用Stream的allMatch,全部匹配则true
- */
- public static void f3_13() {
- // 1.获取Stream流(使用List)
- Stream
girlStream02 = getList().stream(); - // 2.应用Stream的anyMatch,全部匹配则true
- boolean result02 = girlStream02.allMatch(girl -> Objects.equals(girl.getCupSize(), "B"));
- // 3.打印结果
- System.out.println("是否所有的都是B罩杯: " + result02);
- }
-
- /**
- * 3.14 应用Stream的noneMatch
- * 案例: 应用Stream的noneMatch,不存在则true
- */
- public static void f3_14() {
- // 1.获取Stream流(使用List)
- Stream
girlStream03 = getList().stream(); - // 2.应用Stream的anyMatch,不存在则true
- boolean result03 = girlStream03.noneMatch(girl -> Objects.equals(girl.getCupSize(), "G"));
- // 3.打印结果
- System.out.println("是否所有的都是G罩杯: " + result03);
- }
-
- /**
- * 3.15 应用Stream的findFirst
- * 案例: 应用Stream的findFirst,找到第一个元素
- */
- public static void f3_15() {
- // 1.获取Stream流(使用List)
- Stream
stringStream01 = Stream.of("北京", "杭州", "厦门", "苏州"); - // 2.应用Stream的findFirst,找到第一个元素
- Optional
opt01 = stringStream01.findFirst(); - // 3.打印结果
- opt01.ifPresent(city -> System.out.println("第一个: " + city));
- }
-
- /**
- * 3.16 应用Stream的findAny
- * 案例: 应用Stream的findAny,找到任意一个元素
- */
- public static void f3_16() {
- // 1.获取Stream流(使用List)
- Stream
stringStream02 = Stream.of("北京", "杭州", "郑州", "厦门", "苏州"); - // 2.应用Stream的findAny,找到任意一个元素
- Optional
opt02 = stringStream02.findAny(); - // 3.打印结果
- opt02.ifPresent(city -> System.out.println("任意一个: " + city));
- }
4.本例生成数据的函数和Java Bean对象
测试验证需要数据,生成辅助类和方法。
4.1 Java Bean对象
Java Bean对象,包括GirlVo和Girl01,主要使用GirlVo。Girl01在做去重时使用到,因为重写了基类Object的equals(Object obj)和 hashCode()。
(1)GirlVo
- @Data
- @NoArgsConstructor
- @AllArgsConstructor
- @Builder
- public class GirlVo {
- /**ID号*/
- String girlId;
- /**姓名*/
- String girlName;
- /**年龄*/
- long age;
- /**身高*/
- double height;
- /**罩杯*/
- String cupSize;
- }
(2)Girl01
- @Data
- @NoArgsConstructor
- @AllArgsConstructor
- @Builder
- public class Girl01 {
- /**ID号*/
- String girlId;
- /**姓名*/
- String girlName;
- /**年龄*/
- long age;
- /**身高*/
- double height;
- /**罩杯*/
- String cupSize;
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (obj == null || getClass() != obj.getClass()) return false;
- Girl01 var = (Girl01) obj;
- return (Objects.equals(this.girlId, var.girlId));
- }
- @Override
- public int hashCode() {
- return Objects.hash(girlId);
- }
- }
4.2 生成数据的函数
生成数据的函数,包括以下几个。
(1)获取List数据,在List中存放GirlVo对象。
(2)获取Map数据,在Map中存放(key,value)对应(girlId,GirlVo)。
(3)获取Set数据,在Set中存放GirlVo对象。
(4)获取List>。
(5)获取List数据,在List中存放Girl01对象。
- /**
- * 获取List数据,在List中存放GirlVo对象
- */
- public static List
getList() { - List
list = new ArrayList<>(); - GirlVo girl01 = GirlVo.builder().girlId("1001").girlName("张一").age(27).height(169).cupSize("F").build();
- GirlVo girl02 = GirlVo.builder().girlId("1002").girlName("王二").age(29).height(175).cupSize("B").build();
- GirlVo girl03 = GirlVo.builder().girlId("1003").girlName("刘五").age(24).height(160).cupSize("B").build();
- GirlVo girl04 = GirlVo.builder().girlId("1004").girlName("陈六").age(21).height(168).cupSize("C").build();
- GirlVo girl05 = GirlVo.builder().girlId("1005").girlName("赵七").age(25).height(169).cupSize("C").build();
- GirlVo girl06 = GirlVo.builder().girlId("1006").girlName("张八").age(26).height(165).cupSize("A").build();
- list.add(girl01);
- list.add(girl02);
- list.add(girl03);
- list.add(girl04);
- list.add(girl05);
- list.add(girl06);
- return list;
- }
-
- /**
- * 获取Map数据,在Map中存放(key,value)对应(girlId,GirlVo)
- */
- public static Map
getMap() { - Map
map = new HashMap<>(); - List
list = getList(); - Stream
stream = list.stream(); - stream.forEach(girlVo -> {
- map.put(girlVo.getGirlId(), girlVo);
- });
- return map;
- }
-
- /**
- * 获取Set数据,在Set中存放GirlVo对象
- */
- public static Set
getSet() { - Set
set = new HashSet<>(); - List
list = getList(); - Stream
stream = list.stream(); - stream.forEach(girlVo -> {
- set.add(girlVo);
- });
- return set;
- }
-
- /**
- * 获取List
>
- */
- public static List
> getMultiList() {
- List
list01 = new ArrayList<>(); - List
list02 = new ArrayList<>(); - List
> list = new ArrayList<>();
- GirlVo girl01 = GirlVo.builder().girlId("1001").girlName("张一").age(27).height(169).cupSize("F").build();
- GirlVo girl02 = GirlVo.builder().girlId("1002").girlName("王二").age(29).height(175).cupSize("B").build();
- GirlVo girl03 = GirlVo.builder().girlId("1003").girlName("刘五").age(24).height(160).cupSize("B").build();
- GirlVo girl04 = GirlVo.builder().girlId("1004").girlName("陈六").age(21).height(168).cupSize("C").build();
- GirlVo girl05 = GirlVo.builder().girlId("1005").girlName("赵七").age(25).height(169).cupSize("C").build();
- GirlVo girl06 = GirlVo.builder().girlId("1006").girlName("张八").age(26).height(165).cupSize("A").build();
- list01.add(girl01);
- list01.add(girl02);
- list01.add(girl03);
- list02.add(girl04);
- list02.add(girl05);
- list02.add(girl06);
- list.add(list01);
- list.add(list02);
- return list;
- }
-
- /**
- * 获取List数据,在List中存放Girl01对象
- * Girl01是重写了equals(Object obj)和 hashCode()
- * 在使用distinct时去重根据重写规则判断
- */
- public static List
getList01() { - List
list = new ArrayList<>(); - Girl01 girl01 = Girl01.builder().girlId("1001").girlName("张一").age(27).height(169).cupSize("F").build();
- Girl01 girl02 = Girl01.builder().girlId("1002").girlName("王二").age(29).height(175).cupSize("B").build();
- Girl01 girl03 = Girl01.builder().girlId("1003").girlName("刘五").age(24).height(160).cupSize("B").build();
- Girl01 girl04 = Girl01.builder().girlId("1004").girlName("陈六").age(21).height(168).cupSize("C").build();
- Girl01 girl05 = Girl01.builder().girlId("1005").girlName("赵七").age(25).height(169).cupSize("C").build();
- Girl01 girl06 = Girl01.builder().girlId("1001").girlName("张一").age(27).height(169).cupSize("F").build();
- list.add(girl01);
- list.add(girl02);
- list.add(girl03);
- list.add(girl04);
- list.add(girl05);
- list.add(girl06);
- return list;
- }
四、小结
在研究API时,训练是一方面。归纳和分类有助于理解整体思路以及API应用场景。
以上,感谢。
2022年8月21日