java8 List的Stream流操作 (实用篇 三)

目录

[java8 List的Stream流操作 (实用篇 三)](#java8 List的Stream流操作 (实用篇 三))

初始数据

1、Stream过滤:

过滤-常用方法

[1.1 筛选单元素--年龄等于18](#1.1 筛选单元素--年龄等于18)

[1.2 筛选单元素--年龄大于18](#1.2 筛选单元素--年龄大于18)

[1.3 筛选范围--年龄大于18 and 年龄小于40](#1.3 筛选范围--年龄大于18 and 年龄小于40)

[1.4 多条件筛选--年龄大于18 or 年龄小于40 and sex==男](#1.4 多条件筛选--年龄大于18 or 年龄小于40 and sex==男)

[1.5 多条件筛选--年龄大于18 or 年龄小于40 and sex==男 返回姓名(name)集合](#1.5 多条件筛选--年龄大于18 or 年龄小于40 and sex==男 返回姓名(name)集合)

2、Stream去重(集合去重和按元素去重)

去重-常用方法(关键字distinct、concat和利用set、map)

[2.1 关键字distinct去重](#2.1 关键字distinct去重)

[2.2 关键字concat合并和distinct 去重](#2.2 关键字concat合并和distinct 去重)

[2.3 用set集合去重](#2.3 用set集合去重)

[2.4 用map去重--以某个元素去重](#2.4 用map去重--以某个元素去重)

3、Stream拼接(joining)

拼接-常用方法

[3.1 集合内某个字段拼接](#3.1 集合内某个字段拼接)

[3.2 对象内的指定元素map拼接、返回集合](#3.2 对象内的指定元素map拼接、返回集合)

[3.3 对象内的指定元素map拼接、再全部拼接](#3.3 对象内的指定元素map拼接、再全部拼接)

4、Stream分组即组装成map(groupingBy、toMap)

分组-常用方法

[4.1 groupingBy-通过年龄分组](#4.1 groupingBy-通过年龄分组)

[4.2 根据userId组装list对象,对应id的对象的某个属性成组(这里用的userName)](#4.2 根据userId组装list对象,对应id的对象的某个属性成组(这里用的userName))

[4.3 toMap-通过userId分组(key重复会报错)](#4.3 toMap-通过userId分组(key重复会报错))

[4.4 toMap-通过age分组、取前面的值](#4.4 toMap-通过age分组、取前面的值)

[4.5 toMap-通过age分组、取后面的值](#4.5 toMap-通过age分组、取后面的值)

[4.6 toMap-通过男女分组、并且累加age](#4.6 toMap-通过男女分组、并且累加age)

5、Stream排序:

排序-常用方法

[5.1 compareTo 关键字](#5.1 compareTo 关键字)

[5.2 Comparator.comparing() 关键方法](#5.2 Comparator.comparing() 关键方法)

[5.2.1 排序通常和过滤一起使用、如果元素为空会报错](#5.2.1 排序通常和过滤一起使用、如果元素为空会报错)

[5.2.2 多个元素排序方法](#5.2.2 多个元素排序方法)

[5.3 自定义排序](#5.3 自定义排序)

6、Stream统计(count、sum、max、min、average)

统计-常用方法

[6.1 count-获取user集合中年龄大于18岁的人数](#6.1 count-获取user集合中年龄大于18岁的人数)

[6.2 sum-获取user集合中所有人的年纪的总和](#6.2 sum-获取user集合中所有人的年纪的总和)

[6.3 max-获取user集合中所有人年纪最大的人](#6.3 max-获取user集合中所有人年纪最大的人)

[6.4 min-获取user集合中所有人年纪最小的人](#6.4 min-获取user集合中所有人年纪最小的人)

[6.5 average-获取user集合中所有人的年纪的平均值](#6.5 average-获取user集合中所有人的年纪的平均值)

7、Stream分页(skip、limit)

分页-常用方法

[7.1 skip:跳过前n个数据 、limit:获取前n个数据](#7.1 skip:跳过前n个数据 、limit:获取前n个数据)


java8 List的Stream流操作 (实用篇 三)

实际开发的时候想不起来Stream的一些常用方法、去找却很不方便、所以我准备再学一篇实用或者叫常用的stream相关方法的文章。学习整理也是方便查看

结合 java8 List的Stream流操作 (常用篇 一)_java list.stream-CSDN博客

java8 List的Stream流操作 (特别篇 二) toMap_java list tomap-CSDN博客

和实际开发中的需求、按开发使用率排

初始数据

java 复制代码
        List<User> userList = Lists.newArrayList();
        userList.add(new User(1,"天一","男",16,true));
        userList.add(new User(2,"空二","女",19,true));
        userList.add(new User(3,"张三","男",18,true));
        userList.add(new User(4,"李四","女",38,true));
        userList.add(new User(5,"王五","男",18,true));
        userList.add(new User(6,"王六","男",18,true));
        userList.add(new User(7,"王七","男",18,true));
        userList.add(new User(7,"王七","男",18,true));
        userList.add(new User(8,"王七","男",null,true));

1、Stream过滤:

过滤是我们基本必用的 不管是过滤null值还是按条件过滤都是最常用的。

过滤-常用方法

1.1 筛选单元素--年龄等于18
java 复制代码
//筛选单元素--年龄等于18
List<User> filterAgeEqual = userList.stream().filter(user -> user.getAge() == 18).collect(Collectors.toList());
1.2 筛选单元素--年龄大于18
java 复制代码
//筛选单元素--年龄大于18
List<User> filterAgeRange = userList.stream().filter(user -> user.getAge() > 18).collect(Collectors.toList());
1.3 筛选范围--年龄大于18 and 年龄小于40
java 复制代码
//筛选范围--年龄大于18 and 年龄小于40
List<User> filterAgeRange2 = userList.stream().filter(user -> user.getAge() > 18 && user.getAge() < 40).collect(Collectors.toList());
1.4 多条件筛选--年龄大于18 or 年龄小于40 and sex==男
java 复制代码
//多条件筛选--年龄大于18 or 年龄小于40 and sex==男
List<User> filterAgeRange3 = userList.stream().filter(user -> user.getAge() > 18 || user.getAge() < 40 && "男".equals(user.getSex())).collect(Collectors.toList());
1.5 多条件筛选--年龄大于18 or 年龄小于40 and sex==男 返回姓名(name)集合
java 复制代码
//多条件筛选--年龄大于18 or 年龄小于40 and sex==男  返回姓名(name)集合
List<String> nameList = userList.stream().filter(user -> (user.getAge() > 18 || user.getAge() < 40) && "男".equals(user.getSex())).map(User::getUserName).collect(Collectors.toList());

2、Stream去重(集合去重和按元素去重)

去重-常用方法(关键字distinct、concat和利用set、map)

2.1 关键字distinct去重

集合内的对象去重--结果是有序的

java 复制代码
List<User> distinctList = userList.stream().distinct().collect(Collectors.toList());
2.2 关键字concat合并和distinct 去重

concat:合并两个流 distinct:去重

java 复制代码
//concat:合并两个流 distinct:去重
List<User> concatAnddistinctList = Stream.concat(userList.stream(), userList.stream()).distinct().collect(Collectors.toList());
2.3 用set集合去重

集合内的对象去重--结果乱序

java 复制代码
//集合内的对象去重--结果乱序
Set<User> setDistinct = userList.stream().collect(Collectors.toSet());
2.4 用map去重--以某个元素去重

以某个元素去重--用map集合 (v1, v2) -> v1 使用v1是表示保留age(年龄)第一次出现的对象、如果使用v2是保留age(年龄)最后一次出现的对象

java 复制代码
List<User> mapDistinct = userList.stream()
    .collect(Collectors.collectingAndThen(
        Collectors.toMap(User::getAge, Function.identity(), (v1, v2) -> v1),
        map -> new ArrayList<>(map.values())
    ));

3、Stream拼接(joining)

拼接-常用方法

3.1 集合内某个字段拼接

姓名以,拼接

java 复制代码
//姓名以,拼接
String userNameList = userList.stream().map(User::getUserName).collect(Collectors.joining(","));
3.2 对象内的指定元素map拼接、返回集合

每个对象都以 userId-userName-age 拼接、然后返回String集合

java 复制代码
//每个对象都以 userId-userName-age 拼接、然后返回String集合
List<String> strList = userList.stream().map((User user) -> user.getUserId() + "-" + user.getUserName() + "-" + user.getAge()).collect(Collectors.toList());
3.3 对象内的指定元素map拼接、再全部拼接

每个对象都以 userId-userName-age 拼接、再以 , 拼接返回字符串

java 复制代码
//每个对象都以 userId-userName-age 拼接、再以 , 拼接返回字符串
String userIdAndAgeNameAndList = userList.stream().map((User user) -> user.getUserId() + "-" + user.getUserName() + "-" + user.getAge()).collect(Collectors.joining(","));

4、Stream分组即组装成map(groupingBy、toMap)

分组-常用方法

4.1 groupingBy-通过年龄分组
java 复制代码
//groupingBy-通过年龄分组
Map<Integer, List<User>> userGroupingByMap = userList.stream().collect(Collectors.groupingBy(User::getAge));
        userGroupingByMap.forEach((k, v) -> {
            System.out.println(k + ":" + v);
        });
4.2 根据userId组装list对象,对应id的对象的某个属性成组(这里用的userName)
java 复制代码
//根据userId组装list对象,对应id的对象的某个属性成组(这里用的userName)
Map<Integer,List<String>> mp6 = userList.stream().collect(Collectors.groupingBy(User::getUserId, Collectors.mapping(User::getUserName, Collectors.toList())));
4.3 toMap-通过userId分组(key重复会报错)
java 复制代码
//toMap-通过userId分组(key重复会报错)
Map<Integer, User> userToMap = userList.stream().filter(user -> user.getAge() != null).collect(Collectors.toMap(User::getUserId, Function.identity()));
4.4 toMap-通过age分组、取前面的值
java 复制代码
//toMap-通过age分组、取前面的值
Map<Integer, User> userToMap2 = userList.stream().filter(user -> user.getAge() != null).collect(Collectors.toMap(User::getAge, Function.identity(), (v1, v2) -> v1));
4.5 toMap-通过age分组、取后面的值
java 复制代码
//toMap-通过age分组、取后面的值
Map<Integer, User> userToMap3 = userList.stream().filter(user -> user.getAge() != null).collect(Collectors.toMap(User::getAge, Function.identity(), (v1, v2) -> v2));
4.6 toMap-通过男女分组、并且累加age
java 复制代码
//toMap-通过男女分组、并且累加age
Map<String, Integer> userToMap4 = userList.stream().filter(user -> user.getAge() != null).collect(Collectors.toMap(User::getSex, User::getAge, (v1, v2) -> v1 + v2));
userToMap4.forEach((k, v) -> {
    System.out.println(k + ":" + v);
});

5、Stream排序:

开发中有很多都是组装的集合、而要求返回的集合是有序的 (使用率不高的原因是数据库查询支持排序)、

排序-常用方法

单元素排序方法

5.1 compareTo 关键字

(o1, o2) -> o1.getUserId().compareTo(o2.getUserId()) 升序 (o1, o2) -> o2.getUserId().compareTo(o1.getUserId()) 降序

通过指定的userId字段排序

java 复制代码
//升序 只写sorted()默认是升序、 我是为了演示才写完整的、开发中可以直接写sorted()
List<User> sortedCompareTo = userList.stream().sorted((o1, o2) -> o1.getUserId().compareTo(o2.getUserId())).collect(Collectors.toList());

//降序
List<User> sortedReversed= userList.stream().sorted((o1, o2) -> o2.getUserId().compareTo(o1.getUserId())).collect(Collectors.toList());
5.2 Comparator.comparing() 关键方法

默认升序 加reversed()为降序

java 复制代码
//默认升序
List<User> sortedComparator = userList.stream().sorted(Comparator.comparing(User::getUserId)).collect(Collectors.toList());

//reversed()为降序
List<User> sortedComparatorReversed = userList.stream().sorted(Comparator.comparing(User::getUserId).reversed()).collect(Collectors.toList());
5.2.1 排序通常和过滤一起使用、如果元素为空会报错
java 复制代码
//排序通常和过滤一起使用、如果元素为空会报错
List<User> sortedFilter = userList.stream().filter(user -> user.getAge() != null).sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
5.2.2 多个元素排序方法

排序通常和过滤一起使用、 先用age排序、年龄相同再用userId排序(默认是升序)

java 复制代码
//排序通常和过滤一起使用、 先用age排序、年龄相同再用userId排序(默认是升序)
Stream<User> sortedComparators = userList.stream().filter(user -> user.getAge() != null).sorted(Comparator.comparing(User::getAge).thenComparing(User::getUserId));

排序通常和过滤一起使用、 先用age排序升序、年龄相同再用userId排序降序

java 复制代码
//排序通常和过滤一起使用、 先用age排序升序、年龄相同再用userId排序降序
Stream<User> sortedComparatorReverseds = userList.stream().filter(user -> user.getAge()!=null).sorted(Comparator.comparing(User::getAge).thenComparing(User::getUserId).reversed());
5.3 自定义排序

先按年龄再按userId自定义排序(降序)

java 复制代码
//先按年龄再按userId自定义排序(降序)
List<User> sortedCustom = userList.stream().sorted((u1, u2) -> {
    if (Objects.equals(u1.getAge(), u2.getAge())) {
        return u2.getAge() - u1.getAge();
    } else {
        return u2.getUserId() - u1.getUserId();
    }
}).collect(Collectors.toList());

6、Stream统计(count、sum、max、min、average)

统计-常用方法

6.1 count-获取user集合中年龄大于18岁的人数
java 复制代码
//count-获取user集合中年龄大于18岁的人数
Long count = userList.stream().filter(user->user.getAge() > 18).count();
System.out.println("user集合中年龄大于18岁的人数:"+count);
6.2 sum-获取user集合中所有人的年纪的总和
java 复制代码
//sum-获取user集合中所有人的年纪的总和
Long summingLong = userList.stream().map(User::getAge).collect(Collectors.summingLong(Integer::longValue));
System.out.println("user集合中所有人的年纪的总和:"+summingLong);
6.3 max-获取user集合中所有人年纪最大的人
java 复制代码
//max-获取user集合中所有人年纪最大的人
Optional<User> max = userList.stream().max(Comparator.comparing(User::getAge));
System.out.println("user集合中年纪最大的人是:"+max.get().getUserName());
6.4 min-获取user集合中所有人年纪最小的人
java 复制代码
//min-获取user集合中所有人年纪最小的人
Optional<User> min = userList.stream().min(Comparator.comparing(User::getAge));
System.out.println("user集合中年纪最小的人是:"+min.get().getUserName());
6.5 average-获取user集合中所有人的年纪的平均值
java 复制代码
//average-获取user集合中所有人的年纪的平均值
Double average = userList.stream().map(User::getAge).collect(Collectors.averagingDouble(Integer::doubleValue));
System.out.println("user集合中所有人的年纪的平均值:"+ average);

7、Stream分页(skip、limit)

分页-常用方法

7.1 skip:跳过前n个数据 、limit:获取前n个数据
java 复制代码
//skip:跳过前n个数据 、limit:获取前n个数据
List<User> skipAndLimit = userList.stream().skip(1).limit(2).collect(Collectors.toList());
if(!CollectionUtils.isEmpty(skipAndLimit)){
    skipAndLimit.forEach(System.out::println);
}
相关推荐
阿龟在奔跑1 小时前
引用类型的局部变量线程安全问题分析——以多线程对方法局部变量List类型对象实例的add、remove操作为例
java·jvm·安全·list
先鱼鲨生1 小时前
数据结构——栈、队列
数据结构
一念之坤1 小时前
零基础学Python之数据结构 -- 01篇
数据结构·python
IT 青年1 小时前
数据结构 (1)基本概念和术语
数据结构·算法
熬夜学编程的小王1 小时前
【初阶数据结构篇】双向链表的实现(赋源码)
数据结构·c++·链表·双向链表
liujjjiyun2 小时前
小R的随机播放顺序
数据结构·c++·算法
ashane13143 小时前
Java list
java·windows·list
Reese_Cool4 小时前
【数据结构与算法】排序
java·c语言·开发语言·数据结构·c++·算法·排序算法
djk88884 小时前
.net将List<实体1>的数据转到List<实体2>
数据结构·list·.net
搬砖的小码农_Sky5 小时前
C语言:结构体
c语言·数据结构