手把手带你了解Java-Stream流方法学习及总结

 更新时间:2021年08月19日 14:56:17   作者:Java架构-大仙  
这篇文章主要介绍了通过实例了解JavaStream流的方法学习和总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

前言

Stream是一个来自数据源的元素队列并支持聚合操作,其中具有以下特性:

  • Stream只负责计算,不存储任何元素,元素是特定类型的对象,形成一个队列
  • 数据源可以实集合、数组、I/O channel、generator等
  • 聚合操作有类似SQL的:filter、map、match、sorted等操作
  • Stream流的执行类似于懒加载,用户使用时才执行相应操作
  • 可消费性;Stream只能被消费一次,被消费后需要重新生成

本文总结了部分在日常开发中经常接触到的一些Stream流相关的方法,不足之处或有错误欢迎留评,总结的几个方法如下:

  • void forEach() : 迭代流中的数据
  • Stream map() : 用于映射每个元素到对应的结果
  • Stream filter() : 条件过滤器
  • Stream sorted() : 排序
  • R collect() : 流数据 -> 集合/数组
  • 待补充…

forEach()

forEach()源码:

void forEach(Consumer<!--? super T--> action);

Stream().forEach() : 迭代流中的数据

forEach() 的返回类型为void,不会产生新的流

举个栗子:

public void testForEach() {
     /**
      * 使用forEach()内部迭代
      * ints()表示整数类型
      * limit()表示限制流个数(次数)
      */
     Random random = new Random();
     random.ints().limit(10).forEach(System.out::println);
}

运行结果:


再举个灵活一点的栗子:

public void testForEach() {
    /**
     * 使用forEach()转换集合类型,如List->Map
     */
    AtomicInteger i = new AtomicInteger();//原子类型
    Map<Integer,String> map = new HashMap<>();
    List<String> list = new ArrayList<>(Arrays.asList("Hello",",","world"));
    list.stream().forEach(s->{
        map.put(i.getAndIncrement(),s);
    });
}

对于forEach()方法在本人日常开发中常用于:

  • 使用内循环对集合进行遍历
  • 使用foreach方法将List转为Map形式

map()

map()源码:

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

Stream().map() 用于映射每个元素到对应的结果

返回类型为Stream,map()会产生新的流并返回

举个栗子:

public void testMap(){
    /**
     * map()获取list每个元素的平方值
     * distinct()去重操作
     * collect()将map()产生的新的流转为List类型
     */
    List<Integer> list = Arrays.asList(1,2,3);
    list.stream().map(num -> num * num)
                 .distinct()
                 .collect(Collectors.toList())
                 .forEach(System.out::println);
}

filter()

filter()源码:

Stream<T> filter(Predicate<? super T> predicate);

Stream().filter()为条件过滤器

举个栗子:

public void testFilter(){
    /**
     * filter()过滤空字符串
     * count()统计符合条件的个数,返回类型long
     */
    List<String> list = new ArrayList<>(Arrays.asList("ab","","abc","","acd"));
    long count = list.stream()
                     .filter(str -> str.isEmpty())
                     .count();
}

sorted()

sorted()源码:

Stream<T> sorted();
Stream<T> sorted(Comparator<? super T> comparator);

Stream支持两种方式的排序:

无参方法默认为自然排序sorted(Comparator comp) 按自定义比较器进行排序

仍然是举个栗子:

1)无参方法

public void testSorted(){
    /**
     * sort()无参默认为自然排序
     * 返回类型Stream 会产生新的流
     */
    List<String> list = new ArrayList<>(Arrays.asList("aaa","ccc","bbb"));
    list.stream().sorted().forEach(System.out::println);
}

执行结果:

2)带参方法(User类由name和age组成)

  • 先比较年龄,按从小到大排序
  • 若年龄相等,则按性名自然排序
public void testSorted(){
    /**
     * sort(Comparator comp)按自定义比较器进行排序
     * 返回类型同样是Stream 会产生新的流
     */
    List<User> userList = new ArrayList<>(Arrays.asList(
       new User("zhangsan",22),
       new User("wangwu",22),
       new User("badao",32),
       new User("kongfu",16)
    ));
    Stream<User> sorted = userList.stream().sorted((x, y) -> {
        if (x.getAge() == y.getAge()) { // 使用流中的序列两两进行比较
            return x.getName().compareTo(y.getName());
        } else {
            return x.getAge() - y.getAge();//顺序
            // y.getAge() - x.getAge() 为逆序
        }
    });
    sorted.forEach(System.out::println);
}

执行结果:

collect()

collect()源码:

<R> R collect(Supplier<R> supplier,
              BiConsumer<R, ? super T> accumulator,
              BiConsumer<R, R> combiner);

stream().collect() 由三个参数构成 :

1.Supplier 生产者,返回最终

2.结果BiConsumer<R, ? super T> accumulator,累加器 :

其中 R 为要返回的集合, ? super T 为遍历过程中的每个参数,相当于add操作

3.BiConsumer<R,R> combiner,合并器 :

有并行流时才会使用,相当于将第二部操作形成的list添加到最终的list,addAll操作

举个栗子:

1)new()

public void testCollect(){

    Stream<String> stream = Stream.of("hello","world","hello,world");
	
    // new()
    List<String> list = stream.collect(Collectors.toList());//List
    // 指定集合类型,如ArrayList
    ArrayList<String> arrayList = stream.collect(Collectors.toCollection(ArrayList::new));
    //Set
    stream.collect(Collectors.toSet());
    // 指定HashSet
    HashSet<String> hashSet = stream.collect(Collectors.toCollection(HashSet::new));
    // 拼接字符串
    String str = stream.collect(Collectors.joining());

2)new() -> add() -> addAll()

public void testCollect(){
    /**
     * 参数传递行为相当于: new() -> add() -> addAll()
     */
    Stream<String> stream = Stream.of("hello","world","hello,world");
    // new() -> add() -> addAll()完整演示
    HashMap<String,String> map = stream.collect(HashMap::new,(x,y)->{
        x.put(y,y); // x 为集合,y 为当前遍历元素,以当前遍历元素作为kv
    },HashMap::putAll);
    map.forEach((x,y)->{
        System.out.println(x+" : "+y);
    });
    

执行结果:

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

相关文章

  • Redisson分布式锁源码解析

    Redisson分布式锁源码解析

    文章给大家分享了关于Redisson分布式锁源码相关的知识点内容,有兴趣的朋友们可以参考学习下。
    2018-08-08
  • Java实现公众号功能、关注及消息推送实例代码

    Java实现公众号功能、关注及消息推送实例代码

    公众号开发近些年是一个比较热门的方向,下面这篇文章主要给大家介绍了关于Java实现公众号功能、关注及消息推送的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-11-11
  • Java基础之JDBC的数据库连接与基本操作

    Java基础之JDBC的数据库连接与基本操作

    这篇文章主要介绍了Java基础之JDBC的数据库连接与基本操作,文中有非常详细的代码示例,对正在学习java基础的小伙伴们也有很好的帮助,需要的朋友可以参考下
    2021-05-05
  • Spring底层原理由浅入深探究

    Spring底层原理由浅入深探究

    Spring事务有可能会提交,回滚、挂起、恢复,所以Spring事务提供了一种机制,可以让程序员来监听当前Spring事务所处于的状态,这篇文章主要介绍了Spring底层事务原理,需要的朋友可以参考下
    2023-02-02
  • 详细了解MVC+proxy

    详细了解MVC+proxy

    Java有两种代理方式,一种是静态代理,另一种是动态代理。对于静态代理,其实就是通过依赖注入,对对象进行封装,不让外部知道实现的细节。很多 API 就是通过这种形式来封装的
    2021-07-07
  • jmeter正则表达式实例详解

    jmeter正则表达式实例详解

    正则表达式就是记录文本规则的代码。学习正则表达式最好就是从实例下手。下面我们通过实例代码给大家介绍jmeter正则表达式的相关知识,感兴趣的朋友一起看看吧
    2021-12-12
  • 详解springboot+atomikos+druid 数据库连接失效分析

    详解springboot+atomikos+druid 数据库连接失效分析

    本文主要介绍了springboot+atomikos+druid 数据库连接失效分析,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • MyBatis-Plus 实体类注解的实现示例

    MyBatis-Plus 实体类注解的实现示例

    MyBatis-Plus作为MyBatis的增强版,提供了一系列实用的注解,如@TableName、@TableId、@TableField等,旨在简化数据库和Java实体类之间的映射及CRUD操作,通过这些注解,开发者可以轻松实现表映射、字段映射、逻辑删除、自动填充和乐观锁等功能
    2024-09-09
  • SpringBoot项目构建Maven标签及属性用法详解

    SpringBoot项目构建Maven标签及属性用法详解

    在 Spring Boot 项目中,Maven 是最常用的构建工具之一,本文将详细介绍 Maven 依赖管理中的主要标签及其使用方法,帮助开发者更好地理解和使用 Maven 构建工具,感兴趣的朋友跟随小编一起看看吧
    2024-08-08
  • SpringBoot预加载与懒加载实现方法超详细讲解

    SpringBoot预加载与懒加载实现方法超详细讲解

    Spring一直被诟病启动时间慢,可Spring/SpringBoot是轻量级的框架。因为当Spring项目越来越大的时候,在启动时加载和初始化Bean就会变得越来越慢,很多时候我们在启动时并不需要加载全部的Bean,在调用时再加载就行,那这就需要预加载与懒加载的功能了
    2022-11-11

最新评论