java 8 流库

常用的流的操作

java8流库新增的流遵循了 做什么而不是怎么做的原则

  1. 流不会修改其数据源
  2. 流不会储存元素
  3. 流的操作尽量会怠性执行
var str=new String(Files.readAllBytes(Paths.get("d://1.txt")),StandardCharsets.UTF_8);
        List<String> list=List.of(str.split("\\PL+"));
        long count=list.stream().filter(w->w.length()>10).count();
        System.out.print(count+"\n"+list);

在如示代码中,stream会返回一个作用于 该列表的流,filter会返回一个只包含长度大于1

0 的元素的流。count方法将这个流的 元素计数

各种类创建Stream对象的方法效果
String类 stream()返回一个流
String类 parallelStream()返回一个并行的流
Files类 lines()返回一个包含 包含了文件中所有行的流
Arrays类 stream(数组)返回一个流

Stream类的方法效果
filter(Predicate实例)过滤,返回一个满足条件的流
count()返回当前流中的元素数量,这是一个终止操作
of(可变参数.......)返回一个由指定元素创建的流
empty()创建不包含任何元素的流
generate(Supplier接口对象)用于创建无限流
ofNullable(Path对象)用一个对象创建一个 流,仅包含一个元素
iterate(起始值,判断是否继续的对象,进行操作的对象)迭代产生元素,组成这个流,终止操作
filter(筛选条件Predicate)保留符合条件的元素组成的流
map(处理函数)会把这个指定函数依次处理流中的每一个元素,但是将一个元素处理后得到一个流,最后会得到一个包含流的流
flatMap(处理函数)同上,但将流铺开,最后只得到一个流
limit(int n)得到前n个元素的 流
skip(int n)跳过前n个元素的 流
takeWhile(predicate对象)判断为
dropWhile(predicate对象)
concat(流1,流2)static方法,连接两个流
sorted()排序
distinct()去除重复的元素
peek(Consumer实例)取出一个元素
max(Comparator实例)返回最大值,由Optional包装
min(Comparator实例)返回最小值,由Optional包装
fideFirst()找到第一个,由Optional包装
fideAny()找到任意一个,由Optional包装
anyMatch(Predicate实例)查找是否有匹配的,返回boolean,还有allMatch,noneMatch
forEach(Consumer实例)任意顺序遍历,终止操作
forEachOrdered()按顺序遍历,终止操作
toArray()返回Object 数组,终止操作
toArray(String[]::new)像这样传入new 构造方法,会返回一个String数组终止操作
collect(Collector实例)收集操作,返回对应收集器的类型的对象
reduce(二元函数)将每一个元素操作,如同v1 op v2 op v3 .......,由此可以实现累加累乘,最后把结果返回回来
reduce(起始值,二元函数)同上
Collectors类效果
toList()创建一个List收集器
toSet()创建一个Set收集器
toCollection(Suppliers实例)创建一个收集器,如传入TreeSet::new
joining()创建一个字符串收集器,进行拼接
joining(分隔符)同上,指定拼接时的分隔符
toMap(Fuction key,Function value)创建Map收集器
toMap(Fuction key,Function value,key相同时要做的处理)创建Map收集器,并给出key重复时的解决方案
toMap(Fuction key,Function value,key相同时要做的处理,TreeSet::new)创建Map收集器,指定返回 TreeMap对象
partitioningBy(Predicate实例)根据返回的真假来分组
groupingBy(Fuction实例)根据Function返回的值,来将相同的元素编组。这最终会返回一个 Map<T,List>对象
groupingBy(Fuction实例,Collector对象)同上,但值不是列表,而是你指定的,可以用toSet(),指定值变为集合,这里把这种叫做下游收集器
counting()下游收集器,返回列表中元素的个数
summing(Fuction实例)下游收集器,将每个元素被这个函数加工后产生的值,求和
maxBy(Comparator对象)同minBy()下游收集器,返回最大或最小值
[Int][Double][Long] 的接口实例)返回[Int][Double][Long]SummaryStatistics对象
[Int][Double][Long]SummaryStatistics类方法
getCount()返回汇总后的元素个数
getAverage()返回平均
getMax()返回最大
getMin()。。。。。
Optional类效果
orElse(其他值)返回Optional里的值,如果为空就 返回指定的 值
orElseGet(Suppliers实例)返回Optional里的值,如果为空就 返回这个 实例产生的值
orElseThrow(Suppliers实例)返回Optional里的值,如果为空就 抛出这个 实例的结果
ifPresent(Consumer实例)如果 Optional值存在就执行,不存在就不执行
ifPresentOrElse(Consumer实例1,Consumer实例2)如果存在就执行实例1,不存在就执行实例2
isPresent()判断是否存在
of(元素)创建Optional对象
empty()创建Optional对象
ofNullable(元素)如果元素不为null就返回of()的结果,为null就返回empty()的结果
map(Fuction实例)返回一个Optional,里面的值是被map方法处理过的
flatMap(Function实例)同上,如果值不存在,就返回空的Optional
get()得到值
Stream()返回流

基本类型流

以上方法我们都是把整数放 到Stream<Integer>中,这样很低效。因此流库中有专门 对应基础类型的流,

如IntStream(还可以存储short,char,byte,Boolean),LongStream,DoubleStream(可以存储float)。

IntStream.of(1,2,3,4)//
Arrays.stream(数组,from,to)//创建IntStream的几种方法
range(from,to)返回一个该区间步长为1的元素组成的IntSream,左闭右开
rangeClosed(from,to)同上,但左右都闭
boxed()将基本类型流变为普通流

字符串.codePoints() 返回一个IntStream流对象 当你有一个流时,可以用mapToInt,mapToLong,mapToDouble方法 将其转化为基本类型流

基本类型流于普通流的主要差别:

  • toArray()返回一个基本类型数组
  • 产生的可选结果是 OptionalInt或OptionalLong或OptionalDouble,没有get方法,但有getAsInt,getAsLong,getAsDouble方法
  • 具有min,max,average方法

并行流

流使得并行处理变得十分容易,这个过程几乎是自动的。

流的parallel()方法 将一个流转换为并行的流,并且只要在执行最终操作时,这个流是在并行状态,那么中间所有的操作都会被被转换为并行

int arr=new int[12];//统计长度小于12的单词的个数
"I am slh's baba".parallelStream().forEach(
    s->{if(s.length()<12)arr[s]++;});
    //这是非常糟糕的代码,因为是并行的,多个进程不断更新,访问这个
    //数组,会导致错误
Map<Integer,Long> map= "I am slh's baba".parallelStream().filter(
s->s.length<12).collect(groupingBy(String::length,counting()));
//这是将其按长度分组后,统计每组的个数

并行的流的最安全的处理方法就是 调用其自己的函数,将操作交给流本身自己全部进行 线程

在流上调用unordered()方法声明我们对排序不感兴趣,加快速度

Collector 类的gropingByConcurrent()以并行的方式处理,结果是无序的

不要指望把所有流转换为并行流就能加快操作

  • 并行会导致大量开销,只有面对非常大的数据才划算
  • 只有底层数据源能划分为多个部分时,并行才有意义
  • 面对海量的内存数据比网络访问数据更有效

在java9之前,对Files.lines方法返回的流进行并行化是没有意义的,因为不可分。

但现在,该方法用的是内存映射文件,就可以有效分割。

如果要并行化随机数,就不要用Rondom.ints,Rondom.Longs,Rondom.Doubles方法中获得的流为起点,要用SplittableRandom类来

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值