博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JAVA 8 Streams
阅读量:5864 次
发布时间:2019-06-19

本文共 10272 字,大约阅读时间需要 34 分钟。

什么是Stream

首先要说的是,不要被它的名称骗了,这里的Stream跟JAVA I/O中的InputStream和OutputStream是两个不同的概念。Java 8中的Stream其实是函数式编程里Monad的概念,关于Monad,感觉还是比较抽象,不好理解,可以参考,个人觉得还是比较好看懂的,简单说,Monad就是一种设计模式,表示将一个运算过程,通过函数拆解成互相连接的多个步骤,有点链式操作的感觉。

如下,是一个Stream的例子

import java.util.Arrays;import java.util.List;public class Snippet{    public static void main(String[] args)    {        List
myList = Arrays.asList("a1", "a2", "b1", "c2", "c1"); myList .stream() .filter(s -> s.startsWith("c")) //过滤以c字母开头 .map(String::toUpperCase) //字符变成大写 .sorted() //排序 .forEach(System.out::println); //打印输出 }}

使用Stream的好处

  • 对JAVA集合(Collection)对象功能的增强,方便对集合进行各类操作(过滤、求最大值、最小值、统计等);
  • 更加高效,提供串行和并行两种模式,并行模式利用了Java中的fork/join框架技术,能充分利用多核处理器,提高程序并发性;

Stream的特征

  • 不是一个数据结构
  • 为lambda表达式设计
  • 不支持索引访问
  • 很方便的作为数组或集合输出
  • 支持惰性访问
  • 并行计算

如何得到Stream对象

从 Collection 和数组

  • Collection.stream()
  • Collection.parallelStream()
  • Arrays.stream(T array) or Stream.of()

从 BufferedReader

  • java.io.BufferedReader.lines()

静态工厂

  • java.util.stream.IntStream.range()
  • java.nio.file.Files.walk()

自己创建

  • java.util.Spliterator

其它

  • Random.ints()
  • BitSet.stream()
  • Pattern.splitAsStream(java.lang.CharSequence)
  • JarFile.stream()
  • 。。。

Stream的操作类型

Stream有两种类型的操作:Intermediate操作和Terminal操作。

Intermediate(中间操作)

Stream可以进行多次的Intermediate操作,如前面开头的那个例子,其中filter、map、sorted都是Intermediate操作,注意该操作是惰性化的,当调用到该方法的时候,并没有真正开始Stream的遍历。

Terminal(结束操作)

一个Stream只有一个Terminal操作,如前面开头的那个例子,其中forEach就是Terminal操作,Terminal操作是Stream的最后一个操作,这时候才会开始Stream的遍历。

Stream使用示例

 Stream的创建

使用Stream.of

import java.util.stream.Stream;public class StreamBuilders{    public static void main(String[] args)    {        Stream
stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9); stream.forEach(p -> System.out.println(p)); }}

使用Arrays.stream

import java.util.Arrays;import java.util.stream.Stream;public class StreamBuilders{    public static void main(String[] args)    {        Stream
stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9}); stream.forEach(p -> System.out.println(p)); }}

使用Collection.stream() or Collection.parallelStream()

import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.stream.Stream;public class StreamBuilders{    public static void main(String[] args)    {        List
list = new ArrayList
(Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9 })); Stream
stream = list.stream(); //or list.parallelStream(); stream.forEach(p -> System.out.println(p)); }}

使用IntStream.range

import java.util.stream.IntStream;public class StreamBuilders{    public static void main(String[] args)    {        IntStream stream = IntStream.range(1, 9);        stream.forEach(p -> System.out.println(p));    }}

使用Random.ints()

import java.util.Random;import java.util.stream.IntStream;public class StreamBuilders{    public static void main(String[] args)    {        IntStream stream = new Random().ints(1, 10);        stream.forEach(p -> System.out.println(p));    }}

使用Stream.generate()

import java.util.concurrent.TimeUnit;import java.util.stream.Stream;public class StreamBuilders{    static int i = 0;    public static void main(String[] args)    {        Stream
stream = Stream.generate(() -> { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } return i++; }); stream.forEach(p -> System.out.println(p)); }}

其它还有很多,这里暂不一一列出。

Stream类型转集合/数组类型

使用stream.collect(Collectors.toList())

import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.stream.Collectors;import java.util.stream.Stream;public class StreamBuilders{    public static void main(String[] args)    {        List
list = new ArrayList
(Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9 })); Stream
stream = list.stream(); List
evenNumbersList = stream.filter(i -> i % 2 == 0).collect(Collectors.toList()); System.out.print(evenNumbersList); }}

使用stream.toArray(EntryType[]::new)

import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.stream.Stream;public class StreamBuilders{    public static void main(String[] args)    {        List
list = new ArrayList
(Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9 })); Stream
stream = list.stream(); Integer[] evenNumbersArr = stream.filter(i -> i % 2 == 0).toArray(Integer[]::new); System.out.print(Arrays.asList(evenNumbersArr)); }}

其它转为set,map的类似,不一一列出。

Stream核心操作方法

 Intermediate(中间操作),这里只列出常见的几个

filter方法,过滤元素

import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.stream.Stream;public class StreamBuilders{    public static void main(String[] args)    {        List
list = new ArrayList
(Arrays.asList(new String[]{ "Amitabh", "Shekhar", "Aman", "Rahul", "Shahrukh", "Salman", "Yana", "Lokesh"})); Stream
stream = list.stream(); stream.filter((s) -> s.startsWith("A")).forEach(System.out::println); }}

map方法,修改元素

import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.stream.Stream;public class StreamBuilders{    public static void main(String[] args)    {        List
list = new ArrayList
(Arrays.asList(new String[]{ "Amitabh", "Shekhar", "Aman", "Rahul", "Shahrukh", "Salman", "Yana", "Lokesh"})); Stream
stream = list.stream(); stream.filter((s) -> s.startsWith("A")).map(String::toUpperCase).forEach(System.out::println); }}

sorted方法,排序,可以传入自定义排序接口Comparator,

import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.stream.Stream;public class StreamBuilders{    public static void main(String[] args)    {        List
list = new ArrayList
(Arrays.asList(new String[]{ "Amitabh", "Shekhar", "Aman", "Rahul", "Shahrukh", "Salman", "Yana", "Lokesh"})); Stream
stream = list.stream(); stream.sorted().map(String::toUpperCase).forEach(System.out::println); }}

Terminal(结束操作),这里只列出常见的几个

这里的例与前面的类似,就不写出全部代码了,列出重要部分。

forEach方法,迭代元素,并执行相关操作

stream.sorted().map(String::toUpperCase).forEach(System.out::println);

collect方法,从Stream中得到集合

List
memNamesInUppercase = stream.sorted().map(String::toUpperCase).collect(Collectors.toList()); System.out.print(memNamesInUppercase);

Match方法,匹配判断Stream中的元素是否符合指定规则

boolean matchedResult = list.stream().anyMatch((s) -> s.startsWith("A"));        System.out.println(matchedResult);        matchedResult = list.stream().allMatch((s) -> s.startsWith("A"));        System.out.println(matchedResult);        matchedResult = list.stream().noneMatch((s) -> s.startsWith("A"));        System.out.println(matchedResult);

count方法,计数

long totalMatched = list.stream().filter((s) -> s.startsWith("A")).count();        System.out.println(totalMatched);

reduce方法,元素组合操作,常用于字符串拼接、数值的 sum、min、max、average

import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.Optional;public class StreamBuilders{    public static void main(String[] args)    {        List
list = new ArrayList
(Arrays.asList(new String[]{ "Amitabh", "Shekhar", "Aman", "Rahul", "Shahrukh", "Salman", "Yana", "Lokesh"})); Optional
reduced = list.stream().reduce((s1, s2) -> s1 + "#" + s2); reduced.ifPresent(System.out::println); //打印结果:Amitabh#Shekhar#Aman#Rahul#Shahrukh#Salman#Yana#Lokesh }}

Stream短路操作

所谓的短路操作。指的是如果符合要求的话,就不继续执行接下来的操作,类似于&&和||操作,

在Stream中,类似的有anyMatch()和findFirst()方法,

anyMatch(),返回布尔值,只要找到一个匹配的元素,就停止接下来的元素遍历;

boolean matched = list.stream().anyMatch((s) -> s.startsWith("A"));        System.out.println(matched);        // Output: true

findFirst(),返回元素,同样,只返回第一个元素,不会全部遍历;

String firstMatchedName = list.stream().filter((s) -> s.startsWith("L")).findFirst().get();        System.out.println(firstMatchedName);        // Output: Lokesh

并发parallelStream

Java 7引入了Fork/Join并行计算框架,能让我们以并行方式来拆分任务和加速处理过程。通常编写并行代码很难而且容易出错, 但使用 Stream API 无需编写一行多线程的代码,就可以很方便地写出高性能的并发程序。

如下示例:

import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.stream.Stream;public class StreamBuilders{    public static void main(String[] args)    {        List
list = new ArrayList
(Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9 })); // Here creating a parallel stream Stream
stream = list.parallelStream(); Integer[] evenNumbersArr = stream.filter(i -> i % 2 == 0).toArray(Integer[]::new); System.out.print(Arrays.asList(evenNumbersArr)); }}

使用Stream与不用Stream对比

下面给出一个使用Stream与不使用Stream示例,用于统计字符长度为3的字符串个数。

import java.util.Arrays;import java.util.List;public class Java8Tester {   public static void main(String args[]){      List
strings = Arrays.asList("abc", "111", "bc", "efg", "12584","", "1254"); //使用Java 7, 统计字符长度为3的字符串个数 long count = 0; for(String string: strings){ if(string.length() == 3){ count++; } } System.out.println("using java7:Strings of length 3: " + count); //使用Java 8的stream, 统计字符长度为3的字符串个数 count = strings.stream().filter(string -> string.length() == 3).count(); System.out.println("using java8:Strings of length 3: " + count); }}

参考资料

转载于:https://www.cnblogs.com/chenpi/p/5915364.html

你可能感兴趣的文章
数据库安装
查看>>
我的友情链接
查看>>
2018.3.16 12周5次课
查看>>
华为S5500T在Redhat6.4上多路径映射问题
查看>>
我的友情链接
查看>>
纯静态文件环境下的Nginx优化思路
查看>>
Sublime Text 3中文乱码问题
查看>>
mysql用户权限更改
查看>>
POJ 2991 Crane 线段树 向量的旋转变换
查看>>
我的友情链接
查看>>
怎么用pfSense为你的web服务做负载均衡
查看>>
VMware workstation 9发布
查看>>
php编译安装error: Don't know how to define struct flock on this system, set --enable-opcache=no
查看>>
ps 用法
查看>>
emma的几个不足之处
查看>>
Why Not Mix Signed and Unsigned Values in C/C++?
查看>>
关于工资的三个秘密
查看>>
一起学习linux之LAMP环境的搭建
查看>>
windows server 2003 登陆界面变成黑色,用户名和密码的对话框都看不到问题处理...
查看>>
数组去掉重复项并统计出现次数
查看>>