流式编程 stream

流式编程 stream

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(); // 针对整数值进行求和处理

使用Stream步骤

1. 创建Stream;
2. 转换Stream,每次转换原有Stream对象不改变,返回一个新的Stream对象(可以有多次转换)
3. 对Stream进行聚合(Reduce)操作,获取想要的结果;

创建stream

流可以是顺序的也可以是并行的。顺序流的操作是在单线程上执行的,而并行流的操作是在多线程上并发执行的 

创建方法1

可以使用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<Integer> list = ...;

使用List创建一个并行流对象Stream

创建方法2:

Stream<Integer> stream = list.parallelStream();
Stream<Integer> stream = list.stream();

创建方法3:

Collection.stream()用Java集合都创建一个Stream
特殊类型的Stream实现
IntStream、LongStream和DoubleStream
官方建议使用对应类型的Stream?
当然也可以用`Stream<Integer>`、`Stream<Long>`和`Stream<Double>`,但是boxing/unboxing
会很耗时,所以特别为这三种基本数值型提供了对应的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<String> stream = br.lines();


Stream接口创建无限Stream的静态方法

generate()方法接受一个参数函数用来创建无限Stream的静态方法Stream<String> stream = Stream.generate(() -> "test").limit(10);
String[] strArr = stream.toArray(String[]::new);
System.out.println(Arrays.toString(strArr));

iterate()方法接受一个参数函数用来创建无限Stream
Stream<BigInteger> bigIntStream = Stream.iterate(BigInteger.ZERO, n -> n.add(BigInteger.TEN)).limit(10);
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); });

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值