JAVA基础学习总结,day23(Stream 流)

Stream 流

Stream 类似于 生产流水线
特点
1:Stream 不会修改源数据
2:Stream 流的部分操作具有延时性
3:Stream 不能存储元素
4:Stream 流是单向的,不能重复操作

Stream 不是集合元素 JDK8中的一个新特性 被我们称为 流

也不是数据结构 不保存数据 它是有关算法和计算操作的 更像高级别版本的迭代器
Stream 单向 不可往复 数据只能遍历一次 就好比流水 从前面流过了 一去不复返

 不同的地方在于 支持并行化操作

 串行方式
    一个一个依次执行 

    并行 并发
    在一个时间段内 多个操作并发的执行

对一列元素进行操作的步骤
想使用
1:获取流的数据源
2:数据转换
3:按照要求得到结果

流的来源
集合 数组 转换为Stream流

将Stream中数据 收集到集合或者数组中

Stream 中的方法

延迟方法 : 返回值类型仍然是Stream接口自身类型的方法,因此支持链式调用。
Stream filter(Predicate p) 通过该方法 将一个流转换成另一个子集流 (按要求过滤)
参数是一个函数式接口 使用Lambda表达式 表达式完成的事情就是条件判断

 Stream<T> limit(long n) 对流进行截取 只取前n个 ,截取的长度不能大于参数的长度,否则不进行操作

 Stream<T> skip(long n) 跳过前n个元素  截取一个新流

 <R> Stream<R> map(Function<T,R> lambda)  需要将流中元素 映射到另一个流中 使用map方法
                  参数是一个function函数式接口 public R apply(T t);  可以将当前流中的T类型数据 转换为R类型 的流
                  Lambda中就是完成转换功能的 

终结方法 : 返回值类型不再是Stream接口自身类型的方法,
long count() 获取流中的个数 但是这个功能做完 该流程结束
forEach(Consumer lambda) 逐一遍历 (里面是并发元素谁先抢到谁就先出来 )
参数是函数式接口 会将每一个流元素交给该函数进行处理 交给Lambda表达式
接收一个Consumer接口函数,调用public void accept(T t)方法;
静态方法
of(…) 添加数据 形成一个管道
static Stream concat(Stream a,Stream b)
合并流

收集方法
将我们的 流 转换成 List集合
collect(Collectors.toList())

 转换成Set集合
 collect(Collectors.toSet())

  Object[] toArray()
  转换成指定数组
   T[] toArray(len->new T[len])

获取流
Collection stream()方法

import java.util.*;
import java.util.stream.Stream;

public class Demo04GetStream {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        // ...
        Stream<String> stream1 = list.stream();

        Set<String> set = new HashSet<>();
        // ...
        Stream<String> stream2 = set.stream();

        Vector<String> vector = new Vector<>();
        // ...
        Stream<String> stream3 = vector.stream();

根据Map获取流

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;

public class Demo05GetStream {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        // ...
        Stream<String> keyStream = map.keySet().stream();
        Stream<String> valueStream = map.values().stream();
        Stream<Map.Entry<String, String>> entryStream = map.entrySet().stream();
    }
}

根据数组获取流

import java.util.stream.Stream;

public class Demo06GetStream {
    public static void main(String[] args) {
        String[] array = { "张无忌", "张翠山", "张三丰", "张一元" };
        Stream<String> stream = Stream.of(array);
    }
}

并发流:
转换为并发流
S parallel();
直接获取并发流
default Stream parallelStream() {…}

并发流原理介绍
对于并行流,其在底层实现中,是沿用了Java7提供的fork/join分解合并框架进行实现。fork根据cpu核数进行数
据分块,join对各个fork进行合并。实现过程如下所示:

假设现在的求和操作是运行在一台4核的机器上。
在这里插入图片描述
使用注意事项
对于并行流,一定不要陷入一个误区:并行一定比串行快。并行在不同的情况下它不一定是比串行快的。影响并行
流性能主要存在5个因素:

1)数据大小:输入数据的大小,直接影响了并行处理的性能。因为在并行内部实现中涉及到了fork/join操作,它
本身就存在性能上的开销。因此只有当数据量很大,使用并行处理才有意义。

2)源数据结构:fork时会对源数据进行分割,数据源的特性直接影响了fork的性能。

ArrayList、数组或IntStream.range,可分解性最佳,因为他们都支持随机读取,因此可以被任意分割。
HashSet、TreeSet,可分解性一般,其虽然可被分解,但因为其内部数据结构,很难被平均分解。
LinkedList、Streams.iterate、BufferedReader.lines,可分解性极差,因为他们长度未知,无法确定在哪里进行
分割。

3)装箱拆箱
尽量使用基本数据类型,避免装箱拆箱。

4)CPU核数
fork的产生数量是与可用CPU核数相关,可用的核数越多,获取的性能提升就会越大。

5)单元处理开销
花在流中每个元素的时间越长,并行操作带来的性能提升就会越明显。

收集Stream 结果:
Stream流提供collect方法:
<R,A> R collect(collector<? super T,A,R> collector)
参数:Collector
Collectors

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值