引例:

1         List<String> strList = Arrays.asList("zhaojigang","nana","tianya","nana");
2         Stream<String> streamList = strList.stream();//集合转为stream
3         strList = streamList.distinct().filter(str->!str.equals("tianya")).sorted(String::compareTo).collect(Collectors.toList());
4         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)
 1         List<String> strList = Arrays.asList("zhaojigang","nana","tianya","nana");
 2         Stream<String> streamList = strList.stream();//集合转为stream
 3
 4         String[] strArray = {"java","c++","c"};
 5         Stream<String> streamArray = Stream.of(strArray);//数组转为Stream
 6         Stream<String> streamArray2 = Arrays.stream(strArray);//数组转为Stream
 7
 8         Stream<String> streamPartArray = Arrays.stream(strArray, 0, 2);//转换部分数组,范围:[0,2)
 9
10         Stream<String> streamSelf = Stream.of("python","basic","php");//任意元素

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

二、Stream 2 array/collection/String/map

1、stream2array

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

说明:

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

2、stream2collection

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

说明:

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

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

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

4、stream2map(toMap、toConcurrentMap)

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

说明:

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

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

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

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

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

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

5、groupingBy partitioningBy

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

三、filter(Predicate p)

注意:是选择而非过滤

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

注意:

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

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

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

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

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

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

说明:

多条件运算:and or

四、map(Function mapper)

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

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

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

五、reduce 

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

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

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

六、Optional

两种用法:

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

七、limit skip contact

1、limit(long size)

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

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

2、skip(long size)

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

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

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

作用:拼接两个stream

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

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

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

说明:min函数也一样。

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

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

注意:

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

九、原始类型流

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

Stream API的更多相关文章

  1. Java 8 Stream API详解--转

    原文地址:http://blog.csdn.net/chszs/article/details/47038607 Java 8 Stream API详解 一.Stream API介绍 Java8引入了 ...

  2. Atitit 实现java的linq 以及与stream api的比较

    Atitit 实现java的linq 以及与stream api的比较 1.1. Linq 和stream api的关系,以及主要优缺点1 1.2. Linq 与stream api的适用场景1 1. ...

  3. Java 使用 Stream API 筛选 List

    前言 上课的时候看到老师用迭代器来遍历 List 中的元素的时候,我的内心是极其嫌弃的,这种迭代方法不能直接访问当前的元素,而且写起来也麻烦.于是上网查了查 Java 有没有类似于 Linq 的东西, ...

  4. Upgrading to Java 8——第四章 The Stream API

    在这章中我们将学习Stream API,在JDK 8 中的一项新的特性.为了理解这一章的主题,你需要知道如何使用Lambda表达式和java.util.function里的预定义的函数式接口. 一个S ...

  5. Java 8: Lambdas和新的集合Stream API

    Lambda是Java8的主要特色,Java 8: Lambdas & Java Collections | zeroturnaround.com一文介绍了使用Lambda集合处理大量数据的方 ...

  6. Java 8 Stream API Example Tutorial

    Stream API Overview Before we look into Java 8 Stream API Examples, let’s see why it was required. S ...

  7. 第二章 Stream API

    引例: 1 List<String> strList = Arrays.asList("zhaojigang","nana","tiany ...

  8. Java Stream API入门篇

    本文github地址 你可能还没意识到Java对函数式编程的重视程度,看看Java 8加入函数式编程扩充多少类就清楚了.Java 8之所以费这么大功夫引入函数式编程,原因有二: 代码简洁,函数式编程写 ...

  9. Java Stream API性能测试

    已经对Stream API的用法鼓吹够多了,用起简洁直观,但性能到底怎么样呢?会不会有很高的性能损失?本节我们对Stream API的性能一探究竟. 为保证测试结果真实可信,我们将JVM运行在-ser ...

  10. Java 8新特性:新语法方法引用和Lambda表达式及全新的Stream API

    新语法 方法引用Method references Lambda语法 Lambda语法在AndroidStudio中报错 Stream API 我正参加2016CSDN博客之星的比赛 希望您能投下宝贵 ...

随机推荐

  1. android 数据存储&lt;一&gt;----android短信发送器之文件的读写(手机+SD卡)

    本文实践知识点有有三: 1.布局文件,android布局有相对布局.线性布局,绝对布局.表格布局.标签布局等,各个布局能够嵌套的. 本文的布局文件就是线性布局的嵌套 <LinearLayout ...

  2. Scala中的数组和集合操作

    package test /* 1.在scala集合中,Iterable是共同的Trait,Iterable要求继承者实现一些共同的方法,例如元素的遍历 * 2.Array是scala基础的数据结构, ...

  3. [py]编码-强力理解版

    py编码骨灰级总结 思路: python执行py文件步骤--py2/3定义变量时unicode差异 1,py2 py3执行py文件的步骤 2,py2 定义变量x='mao' 1.x='mao', # ...

  4. Centos安装ELK5.3.2

    一.注意情况 1.elk的版本要一致. 2.ElasticSearch是基于lucence开发的,也就是运行需要java支持.所以要先安装JAVA环境.由于es5.x依赖于JDK1.8,所以需要安装J ...

  5. linux 使用文件作为交换分区

    sudo fallocate -l 4G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile ...

  6. C#可扩展数组转变为String[]数组

    简单备忘: 由于需要将数据最终以逗号隔开来拼接,因而写了下面的处理方法. public void GetJoinString() { ArrayList arr = new ArrayList(); ...

  7. C# 开发圆角控件(窗体)

    最近在做卡片视图的程序,要求将控件做成带有圆角的效果,下面是我在网上查找的资料,经过测试,确定可以实现功能.其中方法三既适应于控件,也适应于窗体. 先上传效果图: 方法一: 增加命名空间:using  ...

  8. 021-centos6.5上二进制安装mysql5.7.22

    思路: 下载上传mysql的二进制安装包. 准备好mysql的用户.安装目录basedir.数据目录datadir.配置文件/etc/my.cnf. 初始化出数据库. 配置启动服务. 开机启动. 配置 ...

  9. yii的url写法

    Yii 各种url地址写法 echo Url::home(); 生成入口地址/yii2test/frontend/web/index.php: echo  Url::base();生成入口文件夹地址: ...

  10. 学号20155311 2016-2017-2 《Java程序设计》第9周学习总结

    学号 2016-2017-2 <Java程序设计>第9周学习总结 教材学习内容总结 整合数据库 JDBC(Java DataBase Connectivity)即java数据库连接,是一种 ...