Stream中文称为流,通过将集合转换为这么一种叫做流的元素序列,通过声明性方式,能够对集合中的每个元素进行一系列并行或串行的流水线操作
Java 8中的Stream是对集合Collection对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作或者大批量数据操作。
Stream API借助于同样新出现的Lambda表达式,极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用fork/join并行方式来拆分任务和加速处理过程。通常编写并行代码很难而且容易出错, 但使用Stream API无需编写一行多线程的代码,就可以很方便地写出高性能的并发程序。所以Java 8 中首次出现的 java.util.stream 是一个函数式语言+多核时代综合影响的产物
Stream不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的Iterator。原始版本的Iterator,用户只能显式地一个一个遍历元素并对其执行某些操作;高级版本的Stream,用户只要给出需要对其包含的元素执行什么操作,比如过滤掉长度大于10的字符串、获取每个字符串的首字母等,Stream会隐式地在内部进行遍历,做出相应的数据转换。Stream就如同一个迭代器Iterator,单向,不可往复,数据只能遍历一次,遍历过一次后即用尽了,就好比流水从面前流过,一去不复返。
而和迭代器又不同的是,Stream可以并行化操作,迭代器只能命令式地、串行化操作。顾名思义,当使用串行方式去遍历时,每个item读完后再读下一个item。而使用并行去遍历时,数据会被分成多个段,其中每一个都在不同的线程中处理,然后将结果一起输出。Stream的并行操作依赖于Java7中引入的Fork/Join框架(JSR166y)来拆分任务和加速处理过程。
Stream 的另外一大特点是,数据源本身可以是无限的。
当使用一个流的时候,通常包括三个基本步骤:获取一个数据源source → 数据转换 → 执行操作获取想要的结果。每次转换原有Stream对象不改变,返回一个新的Stream对象(可以有多次转换),这就允许对其操作可以像链条一样排列,变成一个管道
- Integer transactionsIds =
- roomList.stream() //将List转换为stream对象
- .filter(b -> b.getLength() == 10) //针对stream种的数据元素进行过滤,只使用为true
- .sorted((x,y) -> x.getHigh() - y.getHigh()) //针对stream种的数据进行自定义规则的排序
- .mapToInt(Room::getWidth)//从集合元素通过调用当前对象getWidth方法获取对应的int类型数据
- .sum(); // 针对整数值进行求和处理
1. 创建Stream;
2. 转换Stream,每次转换原有Stream对象不改变,返回一个新的Stream对象(可以有多次转换)
3. 对Stream进行聚合(Reduce)操作,获取想要的结果;
流可以是顺序的也可以是并行的。顺序流的操作是在单线程上执行的,而并行流的操作是在多线程上并发执行的
可以使用Arrays.stream()方法来使用Stream
Integer[] array = new Integer[]{3,4,8,16,19,27,23,99,76,232,33,96};
long count = Arrays.stream(array).filter(i->i>20).count();
Collection.parallelStream使用并行流提高性能,处理任务时并行处理,前提是硬件支持,如果单核CPU,只会存在并发处理而不会并行
- ParallelStream在使用上与Stream无区别,本质返回的都是一个流,只不过底层处理时根据条件判断是并行或者是串行
- 并行流并不会按照原本的顺序轨迹执行,而是随机执行,当然对于forEach输出也可以做到顺序串行,
List
使用List创建一个并行流对象Stream
Stream
Stream
Collection.stream()用Java集合都创建一个Stream
特殊类型的Stream实现
IntStream、LongStream和DoubleStream
官方建议使用对应类型的Stream?
当然也可以用`Stream
会很耗时,所以特别为这三种基本数值型提供了对应的Stream
IntStream.of(new int[]{1,2,3}).forEach(System.out::println);
IntStream.range(1,10).forEach(System.out::println);
IntStream.rangeClosed(1,3).forEach(System.out::println)
针对BufferedReader可以生成stream实现一行一行数据的读取
BufferedReader br = new BufferedReader(new FileReader("d:/aaa.txt"));
Stream
generate()方法接受一个参数函数用来创建无限Stream的静态方法Stream
String[] strArr = stream.toArray(String[]::new);
System.out.println(Arrays.toString(strArr));
iterate()方法接受一个参数函数用来创建无限Stream
Stream
BigInteger[] bigIntArr = bigIntStream.toArray(BigInteger[]::new);
System.out.println(Arrays.toString(bigIntArr));
Stream提供了方法forEach来迭代流中的每个数据
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
forEach方法接收一个Lambda表达式,然后在Stream的每一个元素上执行该表达式。不能修改自己包含的本地变量值,
也不能用break/return之类的关键字提前结束循环
numbers.stream().forEach(number->{ System.out.println(number); });