Java8新增的Stream,配合同版本出现的 Lambda ,给我们操作集合(Collection)提供了极大的便利。

文章目录

  • 前言
  • 一、stream是什么?
  • 二、使用步骤
    • 1.得到sream
    • 2.Api操作
  • 总结

前言

在项目和学习中各种各样的集合我们都会使用到,对集合的遍历也是经常会遇到的操作,不管是for循环遍历 还是迭代器遍历 多多少少还是会有一定的冗余。使用Stream流可以一定程度避免代码的冗余,但过度使用也会造成代码可读性变差需要平衡


一、Stream是什么?

  Stream是将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选、排序、聚合等。"流"可以简单理解为流水线, 他的工作就是将传到流水线上的数据做一系列的处理最终得到我们想要的数据,Stream流结合lambda表达式,简化集合与数组的操作,

二、使用步骤

1得到Stream把数据放上去->2使用中间方法对流水线上的数据进行操作->3使用终结方法对流水线上的数据进行操作

1.先得到一条Stream(流水线),把数据放上去

根据不同的数据类型采用不同的处理方式

获取方式 方法名  说明
单列集合 default Stream<E> stream() Collection的默认方法
双列结合 无法直接使用Stream流(需利用keySet或者entrySet)
数组 public static<T> Stream<T> stream(T[] array) Arrays工具类的静态方法
零散数据 public static<T> Stream<T> of(T...values) Stream接口中的静态方法

2.利用Stream流中的API进行各种操作

一般认为Stream流中的Api分两类

中间方法: 方法调用完还可以调用其他方 法如过滤 转换

终结方法: 流中的最后一步 调用完毕后不能调用其他方法 如统计 打印

简单实例代码如下(终结方法):

package stream;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.function.Consumer;
import java.util.stream.Stream;public class StreamDemo2 {public static void main(String[] args) {/** 1.单列集合获取Stream流*/ArrayList<String> list = new ArrayList<>();Collections.addAll(list, "a", "b", "c", "d", "e");//获取一条流水线,并把集合中的数据放到流水线上
//        Stream<String> stream1 = list.stream();
//        //使用终结方打印流水线上的所有数据
//        stream1.forEach(new Consumer<String>() {
//            @Override
//            public void accept(String s) {
//                //s:依次表示流水线上的每一个数据
//                System.out.println(s);
//            }
//        });//上面的打印较为繁琐一般直接链式编程就可以了list.stream().forEach(s -> System.out.println(s));//或者list.stream().forEach(System.out::println);/** 2.双列集合获取Stream流 无法直接获取*///创建双列结合HashMap<String, Integer> hm = new HashMap<>();hm.put("aaa", 111);hm.put("bbb", 222);hm.put("ccc", 333);hm.put("ddd", 444);//获取Stream     hm.stream() 无法获取流 需要利用keySet或者entrySethm.keySet().stream().forEach(k -> System.out.println(k));hm.entrySet().stream().forEach(k -> System.out.println(k));/** 3.数组获取Stream流 Arrays.stream()*/int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};Arrays.stream(arr).forEach(a -> System.out.println(a));//基本数据类型String[] arr1 = {"a", "b", "c"};Arrays.stream(arr1).forEach(s -> System.out.println(s));//引用数据类型/** 4.零散数据获取stream*/Stream.of(1, 2, 3, 4, 5, 6, "a", "b", "c").forEach(s -> System.out.println(s));//Stream.of()的细节 这个方法的形参是可变参数可以传递零散数据 也可传递数组//但是数组必须是 引用数组 基本类型数组会变为一个整体放进流中Stream.of(arr).forEach(a -> System.out.println(a));//[I@378bf509}
}

中间方法示例

名称 说明
Stream<T>fliter(Predicate<? super T>predicate) 过滤
Stream<T>limit(long maxSize) 获取前几个元素
Stream<T>skip(long n) 跳过前几个元素
Stream<T>distinct() 元素去重,依赖(hashCode和equals方法)
static Stream<T>concat(Stream a,Stream b) 合并a和b的流为一个流
Stream<R>map(Function<T,R> mapper) 转换流中的数据类型

注意:中间方法, 返回新的Stream流, 原来的Stream流只能使用一次, 建议使用链式编程. 修改Stream流中的数据, 不会影响原来集合或者数组中的数据

package stream;import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;/*** 将以 张 开头的 有三个字的名字输出*/
public class StreamDemo3 {public static void main(String[] args) {/*filter        过滤limit         获取前几个元素skip          跳过前几个元素distinct      元素去重(依赖hashCode和equals方法)concat        合并a和b两个流为一个map           转换流中的数据类型注意:中间方法, 返回新的Stream流, 原来的Stream流只能使用一次, 建议使用链式编程.修改Stream流中的数据, 不会影响原来集合或者数组中的数据*/ArrayList<String> list = new ArrayList<>();Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰", "张翠山", "张良", "王二麻子", "谢广坤");/* 匿名内部类写法//filter  过滤 把名字以'张'开头的留下 名字大于三个字的留下 其他过滤不要list.stream().filter(new Predicate<String>() {@Overridepublic boolean test(String s) {//如果返回为true 表示当前数据留下//如果返回为false 表示舍弃不要return s.startsWith("张");}}).forEach(s -> System.out.println(s));*///lambda表达式写法 但是原来的Stream流只能使用一次, 建议使用链式编程.
//        Stream<String> stream1 = list.stream().filter(s -> s.startsWith("张"));//此时stream1已经关闭了
//        Stream<String> stream2 = stream1.filter(s -> s.length() == 3);
//        Stream<String> stream3 = stream1.filter(s -> s.length() == 3);
//        //下面的代码会 报错 Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
//        stream2.forEach(s -> System.out.println(s));System.out.println("-------------------将以 张 开头的 有三个字的名字输出------------------------");list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));System.out.println("--------------------原来的list不变-----------------------");//修改Stream流中的数据, 不会影响原来集合或者数组中的数据System.out.println(list);System.out.println("------------------limit------------------------");list.stream().limit(3)//这里的3 是个数 只要前三个 输出: "张无忌","周芷若","赵敏".forEach(s -> System.out.println(s));System.out.println("------------------skip-------------------------");list.stream().skip(4)//跳过4个 输出"张三丰","张翠山","张良","王二麻子","谢广坤".forEach(s -> System.out.println(s));// 只要第4 5 6 个名字 先skip和先limit都一样System.out.println("--------------------只要第4 5 6 个名字-----------------------");list.stream().skip(3).limit(3).forEach(s -> System.out.println(s));System.out.println("-------------------------------------------");list.stream().limit(6).skip(3).forEach(s -> System.out.println(s));System.out.println("===================distinct & concat====================");ArrayList<String> list1 = new ArrayList<>();Collections.addAll(list1, "张无忌", "张无忌", "张无忌", "周芷若", "赵敏", "张强", "张三丰", "张翠山", "张良", "王二麻子", "谢广坤");System.out.println("--------------------distinct-----------------------");list1.stream().distinct().forEach(s -> System.out.println(s));//提示:distinct底层利用hashSet去重System.out.println("------------------concat-------------------------");ArrayList<String> list2 = new ArrayList<>();Collections.addAll(list2, "张麻子", "汤师爷", "黄四郎", "武举人");Stream.concat(list1.stream(), list2.stream()).forEach(s -> System.out.println(s));System.out.println("------------------map-------------------------");ArrayList<String> list3 = new ArrayList<>();Collections.addAll(list3, "张无忌-25", "周芷若-24", "赵敏-23", "张强-18", "张三丰-100", "张翠山-88", "张良-90", "王二麻子-30", "谢广坤-40");//需求 只获取里面的年龄打印出来//  下面的第一个参数是流中原来的数据类型 第二个是要转成之后的类型/*list3.stream().map(new Function<String, Integer>() {@Overridepublic Integer apply(String s) {String[] arr = s.split("-");.return Integer.parseInt(arr[1]);}}).forEach(s -> System.out.println(s));*///精简写法list3.stream().map(s -> Integer.parseInt(s.split("-")[1])).forEach(s-> System.out.println(s));}
}

Stream流的终结方法

名称 说明
void forEach(Consumer action) 遍历
long count() 统计
toArray() 收集流中的数据 放到数组中
collect(Collectior collector) 收集流中的主句 放到集合中

示例:

package stream;import java.util.*;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.stream.Collectors;public class StreamDemo1 {public static void main(String[] args) {/*名称                               说明void forEach(Consumer action) 遍历long count()                  统计toArray()                     收集流中的数据 放到数组中collect(Collectior collector)  收集流中的主句 放到集合中(List Set Map)*/ArrayList<String> list = new ArrayList<>();Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰", "张翠山", "张良", "王二麻子", "谢广坤");System.out.println("---------------------void forEach(Consumer action)-------------------");list.stream().forEach(s -> System.out.println(s));System.out.println("---------------------long count()-------------------");long count = list.stream().count();System.out.println("count="+count);System.out.println("--------------------- toArray()-------------------");Object[] arr1 = list.stream().toArray();System.out.println(Arrays.toString(arr1));System.out.println("----------------------------------------");//IntFunction的泛型: 具体的数组//apply的形参:流中数据的个数 要跟数组长度保持一致//apply的返回值: 具体类型的数组//方法体: 就是创建数组// toArray方法参数的作用: 负责创建一个指定类型数组// toArray方法的底层: 会依次得到流里面的每一个数据 并把数据放到/数组当中// roArray方法的返回值: 是一个装着流里面所有数据的数组/*String[] arr = list.stream().toArray(new IntFunction<String[]>() {@Overridepublic String[] apply(int value) {return new String[value];}});System.out.println(Arrays.toString(arr));*///改为lambda表达式String[] arr2 = list.stream().toArray(value -> new String[value]);System.out.println(Arrays.toString(arr2));System.out.println("---------------------collect(Collector collector)-------------------");ArrayList<String> list1 = new ArrayList<>();Collections.addAll(list1, "张无忌-男-25", "周芷若-女-24", "赵敏-女-22","赵敏-女-22", "张强-男-21", "张三丰-男-25", "张翠山-男-26", "张良-男-35", "王二麻子-男-22", "谢广坤-男-40");//将所有男性收集为另一个集合List<String> newList = list1.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toList());System.out.println(newList);System.out.println("---------------------set-------------------");Set<String> set = list1.stream().filter(s -> "女".equals(s.split("-")[1])).collect(Collectors.toSet());System.out.println(set);System.out.println("---------------------map-------------------");Map<String, Integer> map = list1.stream().filter(s -> "男".equals(s.split("-")[1]))/*toMap : 参数1表示键的生成规则参数2表示值得生成规则参数1:Function泛型1:表示流中每一个数据的类型泛型2:表示Map集合中键的数据类型方法apply形参: 依次表示流中的每一个数据方法体:生成键的代码返回值:已经生成的键参数2:Function泛型1:表示流中每一个数据的类型泛型2:表示Map集合中值的数据类型方法apply形参: 依次表示流中的每一个数据方法体:生成值的代码返回值:已经生成的值*/.collect(Collectors.toMap(new Function<String, String>() {@Overridepublic String apply(String s) {return s.split("-")[0];}},new Function<String, Integer>() {@Overridepublic Integer apply(String s) {return Integer.parseInt(s.split("-")[2]);}}));System.out.println("map="+map);System.out.println("---------------------精简写法-------------------");Map<String, Integer> map1 = list1.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toMap(s -> s.split("-")[0], s -> Integer.parseInt(s.split("-")[2])));System.out.println("map1="+map1);}
}

总结

Java Stream流总结相关推荐

  1. java Stream 流

    java Stream 流 Stream 流 流的创建 流的转化 Optianal 流的计算 Stream 流 1. Stream的定义 来自数据源的支持聚合操作的元素序列. 即一个流对外提供接口,接 ...

  2. 测试Java Stream流 parralle与 sequential的效率

    测试Java Stream流 parralle与 sequential的效率 实验环境 操作系统:win10 处理器:Intel i5-4200U 2核4线程 Java版本:1.8 实验方案 统计大小 ...

  3. Java stream流式计算详解

    Java stream流式计算详解 1. Stream概述 1.1 Stream简介 1.2 Stream分类 2. Stream操作 2.1 Stream创建 2.2 Stream无状态操作 2.3 ...

  4. Java Stream流基础

    Java Stream流基础 何为Steam流? Stream 是对集合数组对象功能的增强,其专注于对集合数组对象进行各种非常便利.高效的聚合操作,或者大批量数据操作.通常我们需要多行代码才能完成的操 ...

  5. Java Stream流之求和

    Java Stream流之求和 流方式实现 基本数据类型 和 包装类型 的一位数组求和 package top.yangbocsu;import java.util.Arrays;/*** @auth ...

  6. Java Stream流的概念

    为什么80%的码农都做不了架构师?>>>    1. Java的流分为 Inputstream 和 OutputStream: 2. 流(stream)的概念源于UNIX中管道(pi ...

  7. Java Stream(流)的分类, 四大基本流的介绍

    上一篇文章已经介绍过什么是流, 以及流的基本概念 http://blog.csdn.net/nvd11/article/details/29917065 本文主要介绍java四大基本流的方法. 一, ...

  8. Java -Stream流和常见函数式接口

    概念 流(Stream)与集合类似,但集合中保存的是数据,而Stream中保存对集合或数组数据的操作. 特点 tream 自己不会存储元素. Stream 不会改变源对象.相反,他们会返回一个持有结果 ...

  9. 深度掌握 Java Stream 流操作,让你的代码高出一个逼格

    概念 Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选.排序.聚合等. Stream` 的操作符大体上分为两种:`中间操作符`和`终止操 ...

最新文章

  1. 高效查看MySQL帮助文档的方法
  2. 我用java爬了一下CSDN,发现了这些秘密。。。
  3. NRPE实现对其它(远端)设备的监控
  4. Understanding Global Unicast IPv6 Addressing
  5. oracle游标理解,oracle游标的使用方法
  6. SuperSocket入门(二)- 探索AppServer、AppSession,Conmmand和App.config
  7. px4官网调参指南 多旋翼无人机PID调参指南
  8. Tomcat集群快速入门2
  9. 前端学习(1925)vue之电商管理系统电商系统之美化一层循环的UI结构
  10. Python正则表达式简单说明(菜鸟教程里面的说明)
  11. .NET库和向后兼容的技巧——第3部分
  12. 基于JAVA+SpringBoot+Mybatis+MYSQL的化妆品售卖系统
  13. 安装依赖以及页面解析
  14. bug10-graphviz.backend.ExecutableNotFound: failed to execute [‘dot‘, ‘-Tpdf‘, ‘-O‘, ‘Source.gv‘]
  15. Teamviewer远程连接提示疑似商业用途处理替代软件
  16. 中国农村统计年鉴合集(1985-2019年)
  17. 微信小程序: 赞赏码的长按识别
  18. Matplotlib学习之subplots函数
  19. VPP学习(二)VPP安装
  20. 笔记本计算机作文,笔记本电脑作文

热门文章

  1. awk oracle,工具: ass109.awk 分析 Oracle 的跟踪文件
  2. Android自定义控件之实现快速检索
  3. C++ 入门导引(这是一篇由GPT4写的文章)
  4. mysql查询所有图书信息_PHP+MySQL使用mysql_num_rows实现模糊查询图书信息功能
  5. CSP-J1 CSP-S1 信奥 第1轮 初赛 数据分析 成绩及分数线汇总
  6. 模拟手机预览(非F12)
  7. 海德汉角度编码器RCN727F与替代型号RCN8390F参数对比
  8. 怎样批量查询网站是否被搜狗收录?批量查询网站搜狗收录的详细教程
  9. DDR3 SPEC
  10. 计算机视觉 专业术语,计算机视觉中常用的术语.doc