引例:

List<String> strList = Arrays.asList("zhaojigang","nana","tianya","nana");
Stream<String> streamList = strList.stream();//集合转为stream
strList = streamList.distinct().filter(str->!str.equals("tianya")).sorted(String::compareTo).collect(Collectors.toList());
strList.forEach(System.out::println);

说明:

  • 第一行:创建数组并转为List
  • 第二行:根据List创建stream
  • 第三行:对该stream进行去重-->选择-->排序-->stream转为List
  • 第四行:遍历该List

以上代码显示了stream API的方便。当然,上边的代码可以更为简洁,如下改为一行:

Arrays.asList("zhaojigang","nana","tianya","nana").stream().distinct().filter(str->!str.equals("tianya")).sorted(String::compareTo).collect(Collectors.toList()).forEach(System.out::println);

以上代码有一个易错点:filter是选择而不是过滤,即filter是选择满足条件的元素

一、创建Stream

三种常用API:

  • 集合-->Stream:stream()
  • 数组-->Stream:Stream.of(T t)或者Arrays.stream(T[] t)
  • 任意元素-->Stream:Stream.of(T... values)
        List<String> strList = Arrays.asList("zhaojigang","nana","tianya","nana");Stream<String> streamList = strList.stream();//集合转为streamString[] strArray = {"java","c++","c"};Stream<String> streamArray = Stream.of(strArray);//数组转为StreamStream<String> streamArray2 = Arrays.stream(strArray);//数组转为StreamStream<String> streamPartArray = Arrays.stream(strArray, 0, 2);//转换部分数组,范围:[0,2)Stream<String> streamSelf = Stream.of("python","basic","php");//任意元素

还有一种:用于产生无限流的,Stream.generate(Supplier<T> s)。

二、Stream 2 array/collection/String/map

1、stream2array

Stream<String> strStream = Stream.of("java","c++","c","python");
Object[] objectArray = strStream.toArray();//只能返回Object[]
String[] strArray = strStream.toArray(String[]::new);//构造器引用(类似于方法引用),可以返回String[]

说明:

通过构造器引用(类似于方法引用),可以构造出具体类型的数组。

2、stream2collection

List<String> strList = strStream.collect(Collectors.toList());//返回List
Set<String> strSet = strStream.collect(Collectors.toSet());//返回set
ArrayList<String> strArrayList = strStream.collect(Collectors.toCollection(ArrayList::new));//收集到指定的List集合,例如收集到ArrayList

说明:

通过构造器引用,可以构造出具体类型的集合。

3、将stream中的元素拼接起来(joining()、joining(","))

Stream<String> strStream = Stream.of("java","c++","c","python");
String str = strStream.collect(Collectors.joining());//将所有字符串拼接起来,结果:javac++cpython
System.out.println(str);String str2 = strStream.collect(Collectors.joining(","));//将所有字符串拼接起来,中间用","隔开,结果:java,c++,c,python
System.out.println(str2);

4、stream2map(toMap、toConcurrentMap)

        Stream<String> strStream = Stream.of("java","c++","c","python");Map<String, Integer> map1 = strStream.collect(Collectors.toMap(Function.identity(), (x)->0));//Function.identity()-->返回strStream中的元素,toMap方法的我两个参数都是Function接口型的,所以第二个参数即使只放0,也不能直接写作0,可以使用如上的方式进行操作for(String key : map1.keySet()){System.out.println("key:"+key+"->"+"value:"+map1.get(key));}//结果/*key:python->value:0key:c++->value:0key:c->value:0key:java->value:0*/

说明:

  • toMap-->stream转为map
  • Function.identity()-->返回stream中的元素

如果key重复的话,这时就会出现问题"duplicate key",采用如下方式解决(增加第三个参数):

Stream<String> strStream = Stream.of("java","c++","c","python","java");
Map<String, Integer> map1 = strStream.collect(Collectors.toMap(Function.identity(), //key(x)->0,             //value(existingValue, newValue) -> existingValue));//如果key重复,取旧值

需要指定返回map的具体类型(增加第四个参数)。

Map<String, Integer> map1 = strStream.collect(Collectors.toMap(Function.identity(), //key(x)->0,             //value(existingValue, newValue) -> existingValue,//如果key重复,取旧值TreeMap::new));//返回TreeMap

注意:每一个toMap就会对应一个相应的toConcurrentMap

5、groupingBy partitioningBy

        /***************************groupingBy partitioningBy**************************/Stream<Locale> localeStream = Stream.of(Locale.getAvailableLocales());Map<String, List<Locale>> country2localeList = localeStream.collect(Collectors.groupingBy(Locale::getCountry));//根据国家分组,groupBy的参数是分类器List<Locale> locales = country2localeList.get("CH");Map<String, Set<Locale>> country2localeSet = localeStream.collect(Collectors.groupingBy(Locale::getCountry, Collectors.toSet()));//根据国家分组,groupBy的参数是分类器,返回setSet<Locale> localeSet = country2localeSet.get("CH");Map<Boolean, List<Locale>> country2locales = localeStream.collect(Collectors.partitioningBy(locale->locale.getLanguage().equals("en")));//分成两组,一组为true(即语言是en的),一组为false(即语言不是en的)List<Locale> trueLocale = country2locales.get(true);

三、filter(Predicate p)

注意:是选择而非过滤

Stream<String> streamSelf = Stream.of("python","basic","php");
streamSelf.filter(str->str.startsWith("p")).forEach(System.out::println);

注意:

  • stream也是可以foreach的,没必要一定要转化成集合再foreach

更好的写法可能是下边这种:

Predicate<String> startCondition = str->str.startsWith("p");
streamSelf.filter(startCondition).forEach(System.out::println);

说明:将条件(通常是lambda表达式)抽取出来。这种方式在多个条件的情况下比较清晰。

注意:函数式接口 = lambda表达式 (即lambda表达式只能返回为函数式接口)

Stream<String> s = Stream.of("java1","java3","java","php12");
Predicate<String> condition1 = str->str.length()==5;//条件1
Predicate<String> condition2 = str->str.startsWith("j");//条件2
s.filter(condition1.and(condition2)).forEach(System.out::println);//and条件

说明:

多条件运算:and or

四、map(Function mapper)

作用:对流中的每一个元素进行操作。

Stream<String> streamSelf = Stream.of("python","basic","php");
streamSelf.map(String::toUpperCase).forEach(System.out::println);

说明:将流内的每一个String全部转换为了大写。

五、reduce 

作用:对stream中的每一个元素做聚合操作。

        Stream<Integer> reduceStream = Stream.of(1,2,3,4,5);Optional<Integer> sumOption = reduceStream.reduce((x,y)->x+y);//计算1+2+3+4+5,即对元素中的元素进行聚合计算,而map是对元素中的每一个元素分别计算(注意:如果stream为null的话,就会产生无效的结果,需要使用Optional接收)//Optional<Integer> sumOption = reduceStream.reduce(Integer::sum);//计算1+2+3+4+5,即对元素中的元素进行聚合计算,而map是对元素中的每一个元素分别计算Integer result = reduceStream.reduce(0, Integer::sum);//0为标识值,即计算:0+1+2+。。+5,如果整个stream为null,就返回标识值。System.out.println(result);

注意:以上是reduce的简单形式,即内联函数是(T,T)->T,即返回值和参数类型是一样的,返回值和参数类型不同的场景需要自己编写函数(用的较少)

六、Optional

两种用法:

  • ifPresent(xxx):存在的就执行xxx,不存在就什么都不执行
  • orElse(xxx):存在就返回存在的值,不存在就返回xxx(可以理解为是默认值)
        Stream<String> optionalStream = Stream.of("java","python","basic");Optional<String> optionValue = optionalStream.filter(str->str.startsWith("p")).findFirst();optionValue.ifPresent(str->System.out.println(str));//if optionalValue为true,即str存在,则输出str,当然也可以使用如下String str = optionValue.orElse("xxx");//如果optionValue为false,即不存在以p开头的字符串时,使用"xxx"来替代System.out.println(str);

七、limit skip contact

1、limit(long size)

作用:截取stream的前size个元素。

Stream<String> streamSelf = Stream.of("python","basic","php");
streamSelf.limit(2).forEach(System.out::println);//截取前两个

2、skip(long size)

作用:跳过stream的钱size个元素

Stream<String> streamSelf = Stream.of("python","basic","php");
streamSelf.skip(2).forEach(System.out::println);//跳过前两个

3、contact(Stream<T>,Stream<T>)

作用:拼接两个stream

Stream<String> streamSelf = Stream.of("python","basic","php");
Stream<String> streamSelf2 = Stream.of("python2","basic2","php2");
Stream.concat(streamSelf, streamSelf2).forEach(System.out::println);

八、聚合函数 count max min findFirst findAny anyMatch allMatch noneMatch

Stream<String> streamSelf = Stream.of("python","basic","php","b");
System.out.println(streamSelf.count());//计算流中的元素个数
Optional<String> largest = streamSelf.max(String::compareToIgnoreCase);//寻找最大值
if(largest.isPresent()){System.out.println(largest.get());
}

说明:min函数也一样。

注意:Optional的使用,上边的是最差的一种形式,见"六"。

        Optional<String> firstMatch = streamSelf.filter(str->str.startsWith("b")).findFirst();//寻找第一个符合条件的元素firstMatch.ifPresent(System.out::println);//这是Optional的第一种用法Optional<String> anyMatch = streamSelf.parallel().filter(str->str.startsWith("b")).findAny();//返回集合中符合条件的任意一个元素,对于并行处理非常好(因为多个线程只要有一个线程找到了,整个计算就会结束)if(anyMatch.isPresent()){System.out.println(anyMatch.get());//这里的结果可能是b,有可能是basic}boolean isAnyMatch = streamSelf.parallel().anyMatch(str->str.startsWith("c"));//集合中是否有一个满足条件System.out.println(isAnyMatch);Stream<String> streamSelf3 = Stream.of("basic","b");boolean isAllMatch = streamSelf3.parallel().allMatch(str->str.startsWith("b"));//集合中是否所有元素都满足条件System.out.println(isAllMatch);boolean isAllNotMatch = streamSelf.parallel().noneMatch(str->str.startsWith("p"));//集合中是否没有一个元素满足条件System.out.println(isAllNotMatch);

注意:

  • optional的最佳用法:ifPresent()-->如果有就输出,如果没有,什么都不做
  • parallel():将stream转为并行流,并行流的使用一定要注意线程安全

九、原始类型流

  • IntStream:int、short、char、byte、boolean
  • LongStream:long
  • DoubleStream:double、float

【Java----JDK8】tream API相关推荐

  1. 【Java 基础】JDK API Documentation 教程使用详解

    文章目录 一.JDK API是什么 二.获取文档 三.文档查看教程 1.大纲 2.目录结构查看 3.包查看 4.类查看 5.详细使用信息 相关 一.JDK API是什么   API(Applicati ...

  2. 【Java编程】05_Java API

    1. API   API(Application Programming Interface,应用程序接口)是一些预先定义的函数.目的是提供应用程序与开发人员基于某软件可以访问的一些功能集,但又无需访 ...

  3. 【JAVA Core】精品面试题100道

    [JAVA Core]精品面试题100道 加个说明:我的初心是Java每个技术栈整理个100道面试题,现在的底子是哪吒的<208道面试题> 后续我会把自己有价值的题和面试真题添加进入,也对 ...

  4. 3.1_2 JavaSE入门 P1 【Java基础】Java语言概述、JDK编译

    相关链接 Excel目录 目录 Part1 Java语言概述 1 Java语言概述 1.1 Java发展史 1.2 java应用平台 1.3 跨平台原理 1.4 JVM JRE JDK 1.5 Ora ...

  5. 【JAVA拾遗】Java8新特性合辑

    [JAVA拾遗]Java8新特性合辑 文章目录 [JAVA拾遗]Java8新特性合辑 0. 逼逼 [--/--]126 Lambda Expressions & Virtual Extensi ...

  6. 【Java自顶向下】试手小公司,面试官问我ConcurrentHashMap,我微微一笑……

    文章目录 ConcurrentHashMap 一.ConcurrentHashMap初始化的剖析 1.1 ConcurrentHashMap初始化 1.2 理解sizeCtl 二.JDK8的添加安全 ...

  7. 【Java自顶向下】面试官:HashMap源码看过吗?我:看过!面试官:好极了,那么来扒一扒吧!

    HashMap 关于hash表的基础内容,请看文章 [数据结构-查找]3.散列表详解 [Java自顶向下]HashMap面试题(2021最新版) 顶层应用 public class HashMapTe ...

  8. 【Java NIO】一文了解NIO

    [Java NIO]一文了解NIO Java NIO 1 背景介绍 在上一篇文章中我们介绍了Java基本IO,也就是阻塞式IO(BIO),在JDK1.4版本后推出了新的IO系统(NIO),也可以理解为 ...

  9. java skip函数_【Java必修课】图说Stream中的skip()和limit()方法及组合使用

    1 简介 本文将讲解Java 8 Stream中的两个方法:skip()和limit().这两个方法是Stream很常用的,不仅各自会被高频使用,还可以组合出现,并能实现一些小功能,如subList和 ...

  10. 【java笔记】Stream流(1)你知道什么叫Stream流吗?

    JDK8 中的 Stream 是对集合(Collection)对象功能的增强,它借助于lambda表达式,更优雅的表达风格,极大的提高编程效率和程序可读性.它针对于对集合对象进行各种非常便利.高效的聚 ...

最新文章

  1. c/c++实现一个密集型server/socket多路复用select
  2. 写了一个 SSO 单点登录的代码示例给胖友!
  3. 【嵌入式】Libmodbus源码分析(五)-TCP相关函数分析
  4. Hadoop生态hive(四)数据类型
  5. JavaScript 删除Cookie
  6. 春节福利:《Oracle性能优化与诊断案例精选》电子版首次公开下载
  7. python在线学习直播-马哥教育官网-专业Linux培训班,Python培训机构
  8. CEGUI的安装简要总结
  9. paip.C#.NET多线程访问 toolStripStatusLabel VC421
  10. 图数据库_多款业界流行图数据库对比
  11. GPS数据解析 GPS 数据格式
  12. hadoop源码研究 编译错误记录
  13. 5.13 利用图层的矢量蒙版打造浪漫情调 [原创Ps教程]
  14. Latex 插入代码(Matlab 或 Python)
  15. 二见钟情之ComboBox显示查询结果集
  16. 企业数字化建设的三个典型误区
  17. Sers微服务快速入门-02.快速接入
  18. c语言课程设计找出肇事车牌,C语言课程设计报告.doc
  19. 继电器是如何成为CPU的
  20. 前端笔记4 JS BOMDOM

热门文章

  1. 数据分析告诉你,薛之谦还能东山再起吗?
  2. MATLAB之数据拟合(附实例+代码)
  3. 股票期货涨跌幅价格计算器
  4. 避障算法 - VO、RVO 以及 ORCA (RVO2)[转载]
  5. 双目相机测距代码演示
  6. MathType和Office 2016兼容设置
  7. 1052. Grumpy Bookstore Owner**
  8. Centos安装Certbot,免费https证书
  9. 【华人学者风采】贾扬清 阿里巴巴
  10. SQL 优化极简法则,还有谁不会?