Java 8 Stream API 基础了解

1.Stream概念
2.数据源
3.中间操作
4.最终操作
5.Stream使用注意事项

1、java.util.stream.Stream概念

*Java API文档解释:支持顺序和并行聚合操作的一系列元素。

*菜鸟教程解释:这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

从菜鸟教程解释中可以看到两个关键词:中间操作、最终操作。Java API的一包操作就是创建类对象,调用方法,所以Stream(流)的使用大概分为三部分:
数据源(通过数据源获取对应的Stream对象)、中间操作、最终操作。

Stream主要特征:
Pipelining:流水线风格,每个中间操作都会返回流对象本身,这样多个操作就可以可做串连起来的管道,经过管道不同部分时进行不同操作*(官方说法补充:如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。)*

内部迭代:当执行中间操作或最终操作时,Stream会自动将每个数据执行一次中间操作方法。(官方:以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。)

2、数据源

用于生成Stream的数据源有两种:集合(单列、双列集合)、数组

  • 获取流
public static void main(String[] args) {/** 1、单列集合Collection:通过调用内部stream()方法获取*/ArrayList<String> list =new ArrayList<>();Collections.addAll(list, "于谦","郭德纲","郭麒麟","孟鹤堂","侯震","岳云鹏","周九良");Stream<String> stream = list.stream();stream.forEach(System.out::println);System.out.println("---------------------------");/** 2、双列集合Map: 通过获取keySet来获取stream,间接获取*/Map<String, String> map = new HashMap<String, String>();map.put("a", "aaaa");map.put("b", "bbbb");Stream<String> stream2 = map.keySet().stream();stream2.forEach(System.out::println);System.out.println("---------------------------");/** 3、数组,通过Arrays的getStream(数组)获取代表该数据源的stream流*/String[] strs = {"11111","22222","33333","44444"};Stream<String> stream3 = Arrays.stream(strs);stream3.forEach(System.out::println);System.out.println("---------------------------");/** 4、Stream还提供了of(...)静态方法和不确定参数形式,来直接获取一批同类型数据源的stream流*/Stream<Integer> stream4 = Stream.of(77,88,99);stream4.forEach(System.out::println);System.out.println("---------------------------");}
  • 通过代码可以看出,还有一种Stream.of(T … values)不确定参数的方法,该方法可以获取一批同类型的数据源的Stream(流),但实际还是数组,该方法调用的是Arrays.stream()方法,Stream.class源码:

  • 而集合使用流的方法都是用的Collection提供的stream()方法。

3、中间操作方法

  • 过滤(filter)

    方法 说明
    Stream filter(Predicate predicate) 返回由与此给定谓词匹配的此流的元素组成的流。

    Predicate是函数式接口,可以使用Lambda表达式

public static void main1(String[] args) {ArrayList<String> list =new ArrayList<>();Collections.addAll(list, "于谦","郭德纲","郭麒麟","孟鹤堂","侯震","岳云鹏","周九良");Stream<String> stream = list.stream();//****************************/** 1、过滤,对应方法Stream<T> filter(Predicate<? extends T> p)*///stream.filter(s->s.startsWith("郭")).filter(s->s.length()==3).forEach(System.out::println);//过滤条件对象--Predicate函数式接口,用Lambda表达式创建对象Predicate<String> p1 = s->s.startsWith("郭");Predicate<String> p2 = s->s.length()==3;//过滤出集合中元素字符串中以“郭”开头,并且长度等于3的元素--and//stream.filter(p1.and(p2)).forEach(System.out::println);//filter等价于filter(p1).filter(p2)//过滤出集合中元素字符串中以“郭”开头,或长度等于3的元素--orstream.filter(p1.or(p2)).forEach(System.out::println);
}
  • 截取和跳过(limit、skip)

    方法 说明
    Stream limit(long maxSize) 截取流的前maxSize个元素形成新的流,
    若maxSize大于原流中数据个数,则只截取原流所有,不报错。
    Stream skip(long n) 跳过前n个数据,用后面的数据作为数据源生成新的Stream(流)

测试代码:

public static void main2(String[] args) {ArrayList<String> list =new ArrayList<>();Collections.addAll(list, "于谦","郭德纲","郭麒麟","孟鹤堂","侯震","岳云鹏","周九良");Stream<String> stream = list.stream();//截取流中数据0-2(前两个),生成新的流//Stream<String> stream2 = stream.limit(2);//stream2.forEach(System.out::println);//跳过前2个,将后面的数据生成新的流//Stream<String> stream3 = stream.skip(2);//stream3.forEach(System.out::println);//跳过前2个,截取剩余数据的前2个生成新的流stream.skip(2).limit(2).forEach(System.out::println);
}
  • 合并和去重复(concat、distinct)

    方法 说明
    Stream concat(Stream a, Stream b) 合并a,b两个Stream(流)成一个Stream
    Stream distinct() 对流中数据去重复后返回新的Stream

测试代码:

public static void main3(String[] args) {ArrayList<String> list =new ArrayList<>();Collections.addAll(list, "于谦","郭德纲","郭麒麟","孟鹤堂","侯震","岳云鹏","周九良");Stream<String> s1 = list.stream().limit(4);Stream<String> s2 = list.stream().skip(2);//将s1,s2连个流合并,打印合并后的流中数据//Stream.concat(s1, s2).forEach(System.out::println);//将s1,s2连个流合并,打印合并后的流中数据---去除重复数据Stream.concat(s1, s2).distinct().forEach(System.out::println);}
  • 映射(map)

    方法 说明
    Stream map(Function mapper) 返回由给定函数应用于此流的元素的结果组成的流。

    map(Function f)方法中参数Function是函数式接口,所以可以使用Lambda表达式

测试代码:

public static void main(String[] args) {ArrayList<String> list =new ArrayList<>();Collections.addAll(list, "于谦","郭德纲","郭麒麟","孟鹤堂","侯震","岳云鹏","周九良");list.stream().map(s->s+"666").forEach(System.out::println);
}

4、最终操作

  • Stream最终操作方法:
方法 说明
long count() 返回此流中的元素数。
void forEach(Consumer action) 对此流的每个元素执行操作。
collect(Collector collector) 收集数据并保存到集合
  • Collector提供的方法:
方法 说明
public static Collector toList() 把元素收集到List集合中
public static Collector toSet() 把元素收集到Set集合中
public static Collector toMap(Function keyMapper,Function valueMapper) 把元素收集到Map集合中

测试代码:

public static void main(String[] args) {ArrayList<String> list =new ArrayList<>();Collections.addAll(list, "于谦","郭德纲","郭麒麟","孟鹤堂","侯震","岳云鹏","周九良");//1、数据遍历(forEach)//将中间操作后剩余的数据进行打印,也可以直接打印原流list.stream().filter(s->s.length()==2).forEach(System.out::println);System.out.println("---------------");//将println静态方法使用Lambda表达式格式传入list.stream().forEach(System.out::println);System.out.println("---------------");//2、统计数据个数(count),也可对源流操作long count = list.stream().filter(s->s.startsWith("郭")).count();System.out.println("姓郭数据个数:"+count);System.out.println("---------------");//3、收集数据封装到集合(collect)List<String> list2 = list.stream().filter(s->s.startsWith("郭")).collect(Collectors.toList());//封装到ListSystem.out.println("List:"+list2);Set<String> set = list.stream().filter(s->s.startsWith("郭")).collect(Collectors.toSet());//封装到SetSystem.out.println("Set:"+set);
}

5、Stream(流)使用注意事项:

  • Stream是按需操作,并不存储数据,所以不会对源数据造成影响。
  • Stream(流)只能进行一次操作,所以在使用时常用链式编程,不声明对象。
  • Stream组成有:数据源、0-n个中间操作、最终操作。
  • 区分中间操作方法很简单,返回结果是Stream的就是中间操作。

Stream使用流程图

参考博客:

【重学Java】Stream流 - gonghr - 博客园 (cnblogs.com)

JDK8新特性之Stream流学习_zhangjun62的博客-CSDN博客_jdk8stream流

Java 8 新特性 | 菜鸟教程 (runoob.com)

java8 Stream stream().filter()进行迭代及实现机制_cv+攻城狮的博客-CSDN博客

jdk8新特性Stream基础了解相关推荐

  1. stream流_最详细的JDK8新特性————Stream流

    Stream流 在Java 8中,得益于Lambda所带来的函数式编程,引入了一个全新的Stream概念,用于解决已有集合类库既有的弊 端. 传统集合的多步遍历代码: 几乎所有的集合(如Collect ...

  2. JDK8新特性Stream流使用详解

    Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据. Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达 ...

  3. Java JDK8新特性Stream流

    1.Stream流 1. 流,支持处理数据处理操作的源生成的元素序列.流有两个重要特性:1流水线:很多流操作本身会返回一个流,这样多的操作就可以链接起来,形成一个大的流水线.2,内部迭代.流的迭代是在 ...

  4. JDK8 新特性Stream流的常用方法

    流表示包含着一系列元素的集合,我们可以对其做不同类型的操作,用来对这些元素执行计算 二.中间流的部分应用 中间操作会再次返回一个流,所以,我们可以链接多个中间操作,注意这里是不用加分号的. /* St ...

  5. 【JDK8 新特性 6】收集Stream流中的结果

    上一篇文章 : (9条消息) [JDK8 新特性 5]Stream流介绍和常用方法的使用_一切总会归于平淡的博客-CSDN博客 目录 1.Stream流中的结果到集合中 2.Stream流中的结果到数 ...

  6. JDK8新特性(三):集合之 Stream 流式操作

    1.Stream流由来 首先我们应该知道:Stream流的出现,主要是用在集合的操作上.在我们日常的工作中,经常需要对集合中的元素进行相关操作.诸如:增加.删除.获取元素.遍历. 最典型的就是集合遍历 ...

  7. JDK8新特性简介、Lambda表达式、Stream流常用api介绍

    JDK8新特性简介.Lambda表达式.Stream流常用api介绍 接口 Java1.8前接口中是不允许有普通方法的,在Java1.8后允许接口中有普通方法,只需要加上default关键字即可: J ...

  8. JDK8新特性知识点总结

    一个简洁的博客网站:http://lss-coding.top,欢迎大家来访 学习娱乐导航页:http://miss123.top/ 1. Open JDK 和 Oracle JDK Java 由 S ...

  9. 【JavaSE之JDK8新特性】三万字详文带你了解JDK8新特性

    JDK8新特性 一.Lambda 1.1需求分析 2.Lambda表达式的初级体验 3.Lambda表达式的语法规则 3.1.Lambda练习1 3.2.Lambda表达式练习2 4.Function ...

最新文章

  1. 【转】微信公共号开发,提示“该公众号暂时无法提供服务,请稍后再试”,如何解决?...
  2. netty源码分析系列——EventLoop
  3. Algorithm:C++语言实现之分治法相关问题(给定实数x和整数n,分治法求xn)
  4. C#中怎样将数组的顺序打乱随机排序
  5. 爬取LeetCode题目——如何发送GraphQL Query获取数据
  6. 异步服务_微服务全链路异步化实践
  7. 犹豫了几个月,我还是跳槽了....
  8. Liferay 6.2 改造系列之十三:修改用户编辑页面表单内容
  9. 国内一二线城市知名IT互联网公司名单
  10. 利用Tampermonkey写脚本抢课
  11. qlabel显示两行_PyQt5 系统化学习: QLabel
  12. 总结:KPCB中国合伙人周炜
  13. luogu P1724 东风谷早苗
  14. 关于android删除语音搜索功能的基本操作方法
  15. 使用联机搜索求解Wumpus World
  16. 稳住!特斯拉电动皮卡
  17. Java代码一键生成神器,支持Jpa/Mybatis/plus多种ORM框架,亲测好用
  18. opencv-基于颜色的目标检测(含代码)
  19. DT时代下数据安全运营面临的主要挑战
  20. Boosting原理及其应用

热门文章

  1. 从我的世界这一款游戏去看存储器
  2. css中图片缩放后不清晰解决方法
  3. DTL with变量
  4. 控制论:轻预测,重反应,做变色龙。
  5. 金融数字新型基础设施创新开放联合体今日成立
  6. 信息检索格式 布尔检索式
  7. 集合经典一练—— 在HashSet集合中添加三个Person对象,把姓名相同的人当做同一个人,禁止重复添加。
  8. GPIO实验(lv9-day12)
  9. QML之PathAnimation路径动画
  10. haproxy mysql 配置_HAProxy + mysql 配置