Java Stream 流的使用

发布于:2024-12-19 ⋅ 阅读:(10) ⋅ 点赞:(0)

Java Stream 流的使用

在实际生产中,几乎很少使用for循环的结构进行操作,Java 8 提供的Stream可以大大提高程序员的生产力,由于自己之前对于Stream 流使用的并不是很熟练,所以在这里进行简单的总结归纳。

最后熟练的使用Stream流,不仅仅是对基础的熟悉,还是需要对于业务的一些理解需要比较深刻。

一、Stream 流的介绍

Stream流是类似于SQL语句,可以通过一种比较直观的方式对java的集合进行运算。

Stream 流,就是将要处理的元素看作是一种流,这个流在管道中运输,我们可以在管道中对管道中的节点进行处理,比如 筛选、排序、聚合 等等。

可以通过以下图,了解流的使用:

+--------------------+       +------+   +------+   +---+   +-------+
| stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect|
+--------------------+       +------+   +------+   +---+   +-------+

Stream流有以下特点:

  • 元素是特定类型的对象,形成一个队列。Java的Stream流不会存储元素,而是按需计算。
  • Stream数据流的来源,可以是集合、数组,I/O,产生器等等。
  • 聚合操作包括filter, map, reduce, find, match, sorted等等。

生成流

  • stream() 为集合创建串行流;目前基本都是串行流
  • parallelStream() 为集合创建并行流

二、使用方式介绍

forEach

forEach可以迭代流中的每个元素。

Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

map

map用于映射每个元素对应的结果。

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
// 获取对应的平方数
List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());

filter

filter可以设置过滤条件。

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 获取空字符串的数量
long count = strings.stream().filter(string -> string.isEmpty()).count();

limit

limit可以用于获取指定数量的流。

Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

sorted

sorted可以对流里面的对象进行排序

Random random = new Random();
random.ints().limit(10).sorted((x,y) -> x.getWeight() - y.getWeight()).forEach(System.out::println);

Collectors

Collectors实现了很多归约操作,可以将流对象转换成集合,hash表(Map)、set、List等等

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
 
System.out.println("筛选列表: " + filtered);
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("合并字符串: " + mergedString);

三、实战举例

1. 创建实体类

public class Organization {
    /**
     * 自增主键
     */
    private Long id;

    /**
     * 组织id
     */
    private Long orgId;

    /**
     * 组织名称
     */
    private String orgName;

    /**
     * 组织简称
     */
    private String simpleName;

    /**
     * 组织标签
     */
    private String labels;

    /**
     * 组织行业
     */
    private String industry;

    /**
     * 状态,1为删除,0为正常
     */
    private Integer status;

    /**
     * 创建时间
     */
    private Long createTime;

    /**
     * 更新时间
     */
    private Long updateTime;
}

2. 创建流

Stream流有两种类型,串行流,大部分基本都是串行流,小部分是并行流。

List<Organization> organizationList = new ArrayList<>();
//1. 创建一个串行stream对象
Stream<Organization> stream = organizationList.stream();
//2. 创建一个并行stream对象
Stream<Organization> parallelStream = organizationList.parallelStream();

3. filter

filter 主要是做筛选, filter括号里面结果满足返回true 不满足返回false,返回结果为return true筛选后的结果

//filter 过滤
organizationList = organizationList.stream().filter(organization -> organization.getId() > 5).collect(Collectors.toList());

//以下是等价的:
organizationList = organizationList.stream().filter(organization -> {
            if (organization.getId() > 5) {
                return true;
            } else {
                return false;
            }
        }).collect(Collectors.toList());

4. forEach

forEach主要用来遍历

//forEach 遍历
organizationList.stream().forEach(System.out::println);

5. map

map可以对里面的对象进行操作,设置元素值,也可以获取对象里面的特定属性,转换为一个集合。

(1)获取自己想要的值
//获取industry属性,并将其转换为list
List<String> industryList = organizationList.stream()
                .map(organization -> organization.getIndustry())
                .collect(Collectors.toList());
        industryList.stream().forEach(System.out::println);
(2) 设置里面的元素的属性
// 将orgName属性设置为New Name + id
organizationList = organizationList.stream().map(organization -> {
            organization.setOrgName("New Name " + organization.getId());
            return organization;
        }).collect(Collectors.toList());

6.controller

特别重要的,需要掌握的一点。可以将流对象转化为各种形式,比如map, list, set等等。

//collect 将流转换为其他形式,如list、set、map等
Map<Long, Organization> organizationMap = organizationList.stream()
        .collect(Collectors.toMap(Organization::getId, organization -> organization));

// map中key重复用这个加(oldValue, newValue) -> oldValue 的方法,保留旧的值
organizationMap = organizationList.stream()
        .collect(Collectors.toMap(Organization::getId, organization -> organization, (oldValue, newValue) -> oldValue));

// 将流转换为list
List<Long> idList = organizationList.stream().map(Organization::getId).collect(Collectors.toList());

// 将流转换为set
Set<Long> idSet = organizationList.stream().map(Organization::getId).collect(Collectors.toSet());

7.sorted

可以对流中的元素进行排序。可以正序,逆序。

//sorted 对流中的元素进行排序
organizationList = organizationList.stream().sorted((o1, o2) -> {
    if (o1.getId() > o2.getId()) {
        return 1;
    } else {
        return -1;
    }
}).collect(Collectors.toList());
//根据Id进行增序排序
organizationList.stream().sorted((o1, o2) -> (int)(o1.getId() - o2.getId())).collect(Collectors.toList());
//根据Id进行降序排序
organizationList.stream().sorted((o1, o2) -> (int)(o2.getId() - o1.getId())).collect(Collectors.toList());

8. count

count可以获取到数量,进行计数

//统计流中的元素数量
long count = organizationList.stream().count();

9.limit

limit可以限制在stream流中获取的个数

//最多获取到前五个数据
organizationList = organizationList.stream().limit(5).collect(Collectors.toList());

10.skip

skip可以跳过数据的个数

//跳过第1个元素
organizationList = organizationList.stream().skip(1).collect(Collectors.toList());

四、组合复杂运算

//1.根据orgId进行分组,分组之后,再将他所属的Id组合起来,将其转换为<Map<Long, List<Long>>形式
Map<Long, List<Long>> getUserList = organizationList.stream()
                .collect(Collectors.groupingBy(
                        Organization::getOrgId,
                        Collectors.mapping(
                                Organization::getId,
                                Collectors.toList()
                        )
                ));

//2.

网站公告

今日签到

点亮在社区的每一天
去签到