首页 > 其他分享 >Stream流的使用

Stream流的使用

时间:2024-05-26 12:04:11浏览次数:26  
标签:Stream stream author 使用 List authors println

目录

一,Stream流

1.1 概述

1.2 Stream代码示例

二,Stream流的使用

2.1 数据准备

2.2 创建流对象

2.3 中间操作

filter

map

distinct

sorted

limit

skip

flatMap

2.4 终结操作

foreach

count

max&min

collect

2.5 查找与匹配

anyMatch

allMatch

noneMatch

findAny

findFirst

2.6 reduce归并

reduce重载方式一:

reduce重载方式二:

2.7 Stream使用注意事项


有关Stream流及函数式编程的相关代码均在我的码云上查看:徐明园/JavaCode - Gitee.com

并内附了详细的Stream流README文档:

一,Stream流

1.1 概述

Java8 的 Stream使用的是函数式编程( 函数式接口及lambda表达式优化函数式接口-CSDN博客 ),主要是用来对 集合或数组进行链状流式 的操作。可以更方便的让我们对集合或数组操作。

1.2 Stream代码示例

在正式使用Stream流操作集合之前,我们先看一个Stream流的代码示例,对比为使用流操作的代码有什么区别:

未使用Stream流:

//查询未成年作家的评分在70以上的书籍 因为作家和书籍可能出现重复,需要进行去重
    List<Book> bookList = new ArrayList<>();
    Set<Book> uniqueBookValues = new HashSet<>();
    Set<Author> uniqueAuthorValues = new HashSet<>();
    for(Author author :authors) {
        if (uniqueAuthorValues.add(author)) {
            if (author.getAge() < 18) {
                List<Book> books = author.getBooks();
                for (Book book : books) {
                    if (book.getScore() > 70) {
                        if (uniqueBookValues.add(book)) {
                            bookList.add(book);
                        }
                    }
                }
            }
        }
    }
    System.out.println(bookList);

使用Stream流:

    List<Book> collect = authors.stream()
            .distinct()
            .filter(author -> author.getAge() < 18)
            .map(author -> author.getBooks())
            .flatMap(Collection::stream)
            .filter(book -> book.getScore() > 70)
            .distinct()
            .collect(Collectors.toList());
    System.out.println(collect);

不难发现使用Stream流之后的代码看上去会简洁很多,减少了很多for循环以及if/else的判断语句,减少了代码的冗余程度,所以我们需要学习Stream流操作集合的原因有一下几个:

  • 能够看懂公司里的代码(现在大部分公司写业务代码都是使用的Stream流,包括作者在的滴滴,所以可见Stream流的重要性);
  • 大数量下处理集合效率高(这也是Stream流的主要作用);
  • 代码可读性高;
  • 减少代码的嵌套;

二,Stream流的使用

2.1 数据准备

首先我们需要定义两个实体类:分别是Book、Author,并使用CreateAuthors类初始化一些数据:

@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode//用于后期去重
public class Author implements Comparable<Author>{
    private Long id;
    private String name;
    private String introduction;
    private Integer age;
    private List<Book> bookList;


    /**
     * 使用sorted时比较整个元素时,要实现比较接口,并重写方法
     */
    @Override
    public int compareTo(Author o) {
        // return 0; // 这里是如何比较
        // 0表示年纪一样大,负数表示传入的大
        // 这里sorted如果输出的是降序,你就把这俩顺序对换就可以了,不用记忆
        return o.getAge() - this.getAge();
    }
}

@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class Book {
    private Long id;
    private String category;
    private String name;
    private Integer score;
    private String introduction;
}

public class CreateAuthors {
    public List<Author> getAuthors() {
        Author author1 = new Author(1L, "徐明园", "my introduction 1", 19, null);
        Author author2 = new Author(2L, "xmy", "my introduction 2", 14, null);
        Author author3 = new Author(2L, "xmy", "my introduction 2", 14, null);
        Author author4 = new Author(4L, "w", "my introduction 4", 12, null);

        List<Book> books1 = new ArrayList<>();
        List<Book> books2 = new ArrayList<>();
        List<Book> books3 = new ArrayList<>();

        // 上面是作者和书
        books1.add(new Book(1L, "类别,分类啊", "书名1", 45, "这是简介哦"));
        books1.add(new Book(2L, "高效", "书名2", 84, "这是简介哦"));
        books1.add(new Book(3L, "喜剧", "书名3", 83, "这是简介哦"));

        books2.add(new Book(5L, "天啊", "书名4", 65, "这是简介哦"));
        books2.add(new Book(6L, "高效", "书名5", 89, "这是简介哦"));

        books3.add(new Book(7L, "久啊", "书名6", 45, "这是简介哦"));
        books3.add(new Book(8L, "高效", "书名7", 44, "这是简介哦"));
        books3.add(new Book(9L, "喜剧", "书名8", 81, "这是简介哦"));

        author1.setBookList(books1);
        author2.setBookList(books2);
        author3.setBookList(books2);
        author4.setBookList(books3);

        return new ArrayList<>(Arrays.asList(author1, author2, author3, author4));
    }
}

2.2 创建流对象

单列集合:集合对象.stream()

List<Author> authors = getAuthors();
Stream<Author> stream = authors.stream();

数组:Arrays.stream(数组对象)或者使用Stream.of()

Integer[] arr = {1,2,3,4,5};
Stream<Integer> stream = Arrays.stream(arr);
Stream<Integer> stream2 = Stream.of(arr);

双列集合:抓换成单列集合之后再创建

Map<String,Integer> map = new HashMap<>();
map.put("蜡笔小新",19);
map.put("黑子",17);
map.put("日向翔阳",16);
Stream<Map.Entry<String, Integer>> stream = map.entrySet().stream();

2.3 中间操作

filter

可以对流中的元素进行条件过滤,符合过滤条件的才能继续留在流中。
//打印所有姓名长度大于1的作家的姓名
List<Author> authors = createAuthors.getAuthors();
authors.stream()
    .filter(author -> author.getName().length()>1)
    .forEach(author -> System.out.println(author.getName()));

map

可以把对流中的元素进行计算或转换。
//将所有作家年龄+10并打印
List<Author> authors = createAuthors.getAuthors();
authors.stream()
    .map(author -> author.getAge())
    .map(age->age+10)
    .forEach(age-> System.out.println(age));

distinct

可以去除流中的重复元素。
//打印所有作家的姓名,并且要求其中不能有重复元素
List<Author> authors = createAuthors.getAuthors();
authors.stream()
    .distinct()
    .forEach(author -> System.out.println(author.getName()));
注意:distinct方法是依赖Object的equals方法来判断是否是相同对象的。所以需要注意重写equals方法。

sorted

可以对流中的元素进行排序。
//对流中的元素按照年龄进行降序排序,并且要求不能有重复的元素。
//法一:
List<Author> authors = createAuthors.getAuthors();
// 对流中的元素按照年龄进行降序排序,并且要求不能有重复的元素。
authors.stream()
    .distinct()
    .sorted()
    .forEach(author -> System.out.println(author.getAge()));

//法二:
List<Author> authors = createAuthors.getAuthors();
// 对流中的元素按照年龄进行降序排序,并且要求不能有重复的元素。
authors.stream()
    .distinct()
    .sorted((o1, o2) -> o2.getAge()-o1.getAge())
    .forEach(author -> System.out.println(author.getAge()));

要想实现对流中元素进行排序,必须对集合对象自定义排序规则,所以sorted操作提供了两种方法:

  • 不带参数的sorted操作:要求对象自定义排序规则,需要实现Comparable接口并重写方法;
  • 带参数的sorted操作:在使用sorted流时自定义排序规则。

limit

可以设置流的最大长度,超出的部分将被抛弃。
//对流中的元素按照年龄进行降序排序,并且要求不能有重复的元素,然后打印其中年龄最大的两个作家的
姓名。
List<Author> authors = createAuthors.getAuthors();
authors.stream()
    .distinct()
    .sorted()
    .limit(2)
    .forEach(author -> System.out.println(author.getName()));

skip

跳过流中的前 n 个元素,返回剩下的元素。
//打印除了年龄最大的作家外的其他作家,要求不能有重复元素,并且按照年龄降序排序。
List<Author> authors = createAuthors.getAuthors();
authors.stream()
    .distinct()
    .sorted()
    .skip(1)
    .forEach(author -> System.out.println(author.getName()));

flatMap

map 只能把一个对象转换成另一个对象来作为流中的元素。而 flatMap 可以把一个对象转换成多个对象作为流中的元素。
//打印所有书籍的名字。要求对重复的元素进行去重。
List<Author> authors = createAuthors.getAuthors();
authors.stream()
    .flatMap(author -> author.getBooks().stream())
    .distinct()
    .forEach(book -> System.out.println(book.getName()));

2.4 终结操作

foreach

对流中的元素进行遍历操作,我们通过传入的参数去指定对遍历到的元素进行什么具体操作。
//输出所有作家的名字
List<Author> authors = createAuthors.getAuthors();
authors.stream()
    .map(author -> author.getName())
    .distinct()
    .forEach(name-> System.out.println(name));

count

可以用来获取当前流中元素的个数。
//打印这些作家的所出书籍的数目,注意删除重复元素。
List<Author> authors = createAuthors.getAuthors();
long count = authors.stream()
    .flatMap(author -> author.getBooks().stream())
    .distinct()
    .count();
System.out.println(count);

max&min

可以用来或者流中的最值。
//分别获取这些作家的所出书籍的最高分和最低分并打印。
//Stream<Author> -> Stream<Book> ->Stream<Integer> ->求值

List<Author> authors = createAuthors.getAuthors();
Optional<Integer> max = authors.stream()
                        .flatMap(author -> author.getBooks().stream())
                        .map(book -> book.getScore())
                        .max((score1, score2) -> score1 - score2);
Optional<Integer> min = authors.stream()
                        .flatMap(author -> author.getBooks().stream())
                        .map(book -> book.getScore())
                        .min((score1, score2) -> score1 - score2);
System.out.println(max.get());
System.out.println(min.get());

这里先大致看一下Optional对象的使用,下一篇博客详细讲解Optional对象!

collect

把当前流转换成一个集合。
//获取一个存放所有作者名字的List集合。
List<Author> authors = createAuthors.getAuthors();
List<String> nameList = authors.stream()
                        .map(author -> author.getName())
                        .collect(Collectors.toList());
System.out.println(nameList);

2.5 查找与匹配

anyMatch

可以用来判断是否有任意符合匹配条件的元素,结果为 boolean 类型。
//判断是否有年龄在29以上的作家
List<Author> authors = createAuthors.getAuthors();
boolean flag = authors.stream()
               .anyMatch(author -> author.getAge() > 29);
System.out.println(flag);

allMatch

可以用来判断是否都符合匹配条件,结果为 boolean 类型。如果都符合结果为 true ,否则结果为 false 。
//判断是否所有的作家都是成年人
List<Author> authors = createAuthors.getAuthors();
boolean flag = authors.stream()
               .allMatch(author -> author.getAge() >= 18);
System.out.println(flag);

noneMatch

可以判断流中的元素是否都不符合匹配条件。如果都不符合结果为 true ,否则结果为 false。
//判断作家是否都没有超过100岁的。
List<Author> authors = createAuthors.getAuthors();
boolean b = authors.stream()
            .noneMatch(author -> author.getAge() > 100);
System.out.println(b);

findAny

获取流中的任意一个元素。该方法没有办法保证获取的一定是流中的第一个元素。
//获取任意一个年龄大于18的作家,如果存在就输出他的名字
List<Author> authors = createAuthors.getAuthors();
Optional<Author> optionalAuthor = authors.stream()
                                  .filter(author -> author.getAge()>18)
                                  .findAny();
optionalAuthor.ifPresent(author -> System.out.println(author.getName()));

findFirst

获取流中的第一个元素。
//获取一个年龄最小的作家,并输出他的姓名。
List<Author> authors = createAuthors.getAuthors();
Optional<Author> first = authors.stream()
                        .sorted((o1, o2) -> o1.getAge() - o2.getAge())
                        .findFirst();
first.ifPresent(author -> System.out.println(author.getName()));

2.6 reduce归并

对流中的数据按照你指定的计算方式计算出一个结果。(缩减操作) reduce 的作用是把 stream 中的元素给组合起来,我们可以传入一个初始值,它会按照我们的计算方式依次拿流中的元素和初始化值进行计算,计算结果再和后面的元素计算。

reduce重载方式一:

T result = identity;
for (T element : this stream)
    result = accumulator.apply(result, element)
return result;
其中 identity 就是我们可以通过方法参数传入的初始值, accumulator 的 apply 具体进行什么计算也是我们通过方法参数来确定的。 例一:
//使用reduce求所有作者年龄的和
List<Author> authors = createAuthors.getAuthors();
Integer sum = authors.stream()
              .distinct()
              .map(author -> author.getAge())
              .reduce(0, (result, element) -> result + element);
System.out.println(sum);

例二::

//使用reduce求所有作者中年龄的最大值
List<Author> authors = createAuthors.getAuthors();
Integer max = authors.stream()
                      .map(author -> author.getAge())
                      .reduce(Integer.MIN_VALUE, (result, element) -> result < element
                      ? element : result);
System.out.println(max);

reduce重载方式二:

boolean foundAny = false;
T result = null;
for (T element : this stream) {
    if (!foundAny) {
        foundAny = true;
        result = element;
    } else
        result = accumulator.apply(result, element);
}
return foundAny ? Optional.of(result) : Optional.empty();

例一:

//使用reduce求所有作者中年龄的最小值
List<Author> authors = createAuthors.getAuthors();
Optional<Integer> minOptional = authors.stream()
                                .map(author -> author.getAge())
                                .reduce((result, element) -> result > element ? element :
                                result);
minOptional.ifPresent(age-> System.out.println(age));

2.7 Stream使用注意事项

  • 惰性求值(如果没有终结操作,没有中间操作是不会得到执行的);
  • 流是一次性的(一旦一个流对象经过一个终结操作后。这个流就不能再被使用);
  • 不会影响原数据(我们在流中可以多数据做很多处理。但是正常情况下是不会影响原来集合中的元素的。这往往也是我们期望的)。

标签:Stream,stream,author,使用,List,authors,println
From: https://blog.csdn.net/qq_47908816/article/details/139210706

相关文章

  • 快团团大团长帮卖团长如何使用【直播工具】进行跨团直播?免费教程一学就会!
    快团团大团长帮卖团长如何使用【直播工具】进行跨团直播?在快团团直播卖货,动销快、做活动方便,为许多团长生意带来显增。各类目团长的直播百花齐放,盲盒开箱、生鲜冷链、跨境美妆、母婴个护……有团长的直播间观看人均价值高达65RMB,几乎百分百转化!一场2小时带货几十万!【直播团......
  • FFmpeg开发笔记(二十三)使用OBS Studio开启RTMP直播推流
    ​OBS是一个开源的直播录制软件,英文全称叫做OpenBroadcasterSoftware,广泛用于视频录制、实时直播等领域。OBS不但开源,而且跨平台,兼容Windows、MacOS、Linux等操作系统。OBS的官网是https://obsproject.com/,录制软件名叫OBSStudio,它基于QT+FFmpeg编码。使用OBS实现直播功能的......
  • 在微服务架构中使用token exchange主要的优势
    在微服务架构中使用tokenexchange有以下几个主要的优势:服务解耦:微服务之间通过tokenexchange进行解耦,每个服务只需关注自身的功能实现,而不需要关心其他服务的具体实现细节。这样可以提高系统的灵活性和可扩展性。安全性:通过tokenexchange进行服务间的认证和授权,可以......
  • MyBatis-Plus分页插件使用
    MyBatis-Plus分页插件使用官方文档https://baomidou.com/plugins/pagination/基本介绍MyBatis-Plus的分页插件PaginationInnerInterceptor提供了强大的分页功能,支持多种数据库,使得分页查询变得简单高效。使用:创建MybatisPlusConfig,并注入容器@Configurationpubl......
  • 使用Autofit.js和React实现自适应布局
    1.什么是Autofit.js?Autofit.js是一个用于自适应网页布局的JavaScript库,它可以根据元素的尺寸和屏幕的大小,自动调整布局和排列方式,以适应不同的设备和分辨率。它提供了简单易用的API,可以帮助我们轻松实现各种自适应效果。2.如何在React中使用Autofit.js?首先,我们需要安装......
  • cBioPortal 数据库 API 使用
    cBioPortal数据库API使用文章目录cBioPortal数据库API使用前言RPythoncBioPortalData1.数据结构2.API3.可视化3.1绘制K-M生存曲线3.2展示样本数最多的20种癌型3.3展示突变频率最高的20基因Python1.基本使用获取基因信息获取样本信息获取临床信息......
  • 使用benthos 实现stream load入库到doris
    下面给出yaml配置,只有input和output,中间可以自定义数据转换pipeline当前的数据从kafka中取出来就是json格式,所以不需要进行处理转换,输出段使用http_client组件,配置批处理提高吞吐量input:broker:copies:9inputs:-kafka:addresses:......
  • powerbuildr中如何使用dblink连接的表
    powerbuilder中如何使用dblink跨库中的表在powerbuilder中使用查询语句并返回值1、定义变量intll_rtn//返回值stringls_sql,ls_where //sql变量和where条件2、写dblink关联表ls_sql="selectcount(1)fromtable1@dblinka"+'~r~n'+& "innerjointable2@dblink......
  • 【使用Python3实现一个音视频播放的工具,同时实现一些自动化的功能,比如视频格式转换,视
    最近有个想法,就是使用python工具自动识别视频文件中的高潮部分#1,主要用途可以有以下几个:转换视频格式识别体育比赛中的高潮部分同样也适用识别电影中的高潮部分截取视频文件中的高潮部分,做成一个视频集锦2,搜索了一圈。使用以下组合开发了一个雏形项目。命名为movie项目。......
  • 软考高级之redis中使用zset实现延迟队列,你答对了么?
    实现延迟队列的思路zset的特性,带有分数的排序,以时间戳作为分数进行排序添加任务zdd取出任务zrangbyscore执行任务zrem定时任务publicstaticvoidmain(String[]args){Jedisjedis=newJedis("ip",6379);TimerTasktask=newTimerTask()......