栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java高级特性第一章(Java8的流库)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java高级特性第一章(Java8的流库)

Java高级特性第一章(Java8的流库)

文章目录
  • Java高级特性第一章(Java8的流库)
    • 前言
  • 1.1 流迭代
    • 流迭代总结
  • 1.2 流的创建
        • 只传两个参数时
        • 多传一位参数时
      • 注意
    • 重点
  • 1.3 filter.map和flatMap方法
    • 假设
        • ★★ 在流之外也会发现有`flatMap`方法因为它是计算机科学中的一种通用的概念.
        • 补充:
  • 1.4 抽取子流和组合流
          • 抽取子流和组合流总结
  • 结尾

前言

提示:本文是OGtwelve学习高级特性时所总结内容;


1.1 流迭代

流迭代

Long count  = words.stream().filter(w -> w.length()>12).count();
//使用名为count的Long类型接收; 先获取words字符串集的流,并通过filter进行过滤(判断长度大于12的字符串)并最后进行个数统计

并行流

Long count = words.parallelStream().filter(w -> w.length()>12).count()

在上方示例中,filter会根据条件返回一条新流,count的作用是将流的个数化简为一个结果,streamparallerStream为创建,filter为转换,count为终止


流迭代总结

流的操作不会修改其数据源
例如: filter则生成新的流,不包括被滤掉的元素
(filter生成过滤后的新流并不包含过滤掉的元素)
(流的操作是惰性执行的,也就意味着找到流中最后一个元素才会执行,因此甚至可以操作无限流)

1.2 流的创建
  1. 可以用Collection接口的Stream方法将任何集合转换为一个流 , 如有数据 , 可用
    Stream words = Stream.of(contents.split("//PL+"));
    of方法具有可变长参数 , 因此可以构建具有任意数量引元的流.
    [Stream接口有两个用于创建无限流的静态方法generate();方法会接收一个不包含任何引元的函数(或者从技术上讲,是一个Supplier接口对象)]
  2. 使用Array.stream(array,from,to);可以用数组中的一部分元素来创建一个流.
  3. 创建不包含任何元素的流,可以用Stream.empty();方法.

常量值的流:

Stream echos = stream.generate(() -> "Echo");

随机数的流:

Stream randoms = stream.generate(Math::random);

※※ 要产生(0,1,2,3…N)这样的序列,可以使用iterate方法,它会接收一个种子值,以及一个函数(准确的说是一个UnaryOpreation;),并会反复地将该函数应用到之前的结果上.

例如:

Stream integers = Stream.iterate(BigInteger.Zero,n -> n.add(BigInteger.One)) ;
//在该序列中,第一个元素是BigInteger.ZERO,第二个元素是f(seed),即是1(大整数BigInteger),
//下一个元素为f(f(seed),即是2;后续以此类推

※※ 如果要产生一个有限序列,则需在参数后添加一个谓词 (参数) 来描述迭代应如何结束
例如:

var limit = new Integer("10000000");
Stream integers = Stream.iterate(BigInteger.Zero , n -> compareTo(limit) < 0, n -> n.add(BigInteger.One))

(只要该谓词拒绝了某个迭代生成的值 , 这个流即结束)

只传两个参数时

:(第一个值为类型,第二个值为UnaryOpreation类型)

多传一位参数时

:(再多传一位时,第二个值为(lambda)表达式,之前第二个值的位置即被推到第三个值的位置.)


Stream.ofNullable方法会用一个对象来创建一个非常短的流.
如果该值判断为null,则这个流的长度为0(仅长度为0,依然存在一条流),当不为null时,长度则为1,内容即为当前判断的该对象.(与flatMap结合最适用)

注意

Java的API接口中有大量方法可以产生流 ;


示例1
例如Pattern类下有一个splitAsStream方法,会按照某个正则表达式来分割一个charSequence对象.

Pattern.compile("//PL+").splitAsStream(contents);
//contents为要分割的charSequence对象

示例2
Scanner.tokens方法会产生一个扫描器的符号流,另一种从字符串获取单词流.

Stream words = new Scanner(contents).tokens();
//contents依旧为需要获取tokens的内容

示例3
静态的File.lines方法会返回一个包含了文件中所有行的Stream;

try(Stream lines = File.lines(path)){
	Process lines.//处理获取到的流
}
//path在这里是文件的路径

示例4
如果持有的Iterable对象不是集合,那么可以通过下方转换为一个流

StreamSupport.stream(iterable.spliterator(),false);

如果持有的Iterable对象是集合并希望得到一个由它的结果构成的流,那么例:

StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator,spliterator.ORDERED),false);
//转换流的时候,将未知大小的分辨卸载第一个值的位置,boolean类型的判断依旧存在于句尾.

重点
  1. 在执行流的操作的时候,并没有修改流背后的集合.
  2. 流并没有收集其数据,数据一直存储在单独的集合中.
  3. 如果修改了该集合,那么流操作的结果就会变成未定义的
    (JDK文档称这种要求为不干涉性)

准确的说,因为中间流的操作是惰性的,即在终止处执行,集合有可能已经发生了变化。
(执行后原流的值被更新,差不多是一个即时时效性的问题,一般线程同步sync或平行parallel来解决 --> 括号内部分方便理解自己定义的)

1.3 filter.map和flatMap方法

流的转换会产生一个新的流,它的元素会派生自另一个流中的元素,我们已经看到了filter转换会产生一个新流,它的元素与某种条件相匹配.

1.这部分将一个字符串专户那位只包含长单词的另一个流.

List words = "...";
Stream longWords = words.stream().filter(w -> w.length()>12);//与1.1部分中的语句一致
//filter这的引元是Predicate,即从 T 到 boolean 的函数

2.这部分将获取到的内容进行小写重组

Stream lowerCaseWords = words.stream().map(String::toLowerCase);

当然在这用了map方法,通常用lambda表达式即可.

3.存入获取到内容的首字母

Stream firstLetters = words.stream().map(s -> s.subString(0,1));

在使用map时,会有一个函数应用到每个元素上,并且其结果是包含了应用该函数后所产生所有结果的流。现在,假设有一个函数,返回的不是一个值,而是一个包含多个值的流。
例如:(展示的方法将字符串转换为字符串流,即一个个的编码点);

public static Stream codePoints(String s){
	var result = new ArrayList();
	int a = 0;
	while(i < s.length()){
		int j = s.offsetByCodePoints(i,1);
		result.add(s.subString(i,j))
		i = j;
	}
	return result.stream();
}

这个方法可以正确地处理需要用两个char值来表示Unicode字符
例如,codePoints("boat")的返回值是["b","o","a","t"];

假设

将上方方法映射到一个字符串上

Stream> result = words.stream().map(w -> codePoints(w));

假如[...["A","B"],["C","D"]...]这样的流想转化为[...["A","B","C","D"]...]这样的,可以使用flatMap方法而不是map方法

Stream flatResult = words.stream().flatMap(w -> codePoints(w));
★★ 在流之外也会发现有flatMap方法因为它是计算机科学中的一种通用的概念.

节后复习:
假设有一个泛型 G( 例如 Stream ),以及将某种类型 T 转换为 G 的函数 f 和将类型 u 转换为 G 的函数 g;
可以通过flatMap来组合它们,即首先应用f,然后应用g,那么以上即为★单子论的关键概念.

补充:

1.产生一个流,它包含当前流中所有满足谓词 (参数) 条件的元素.

Stream filter(Predicate predicate);

2.产生一个流,它包含将mapper应用于当前流中所有元素所产生的结果

 Stream Map(Function mapper)

3.产生一个流,它是通过将mapper应用于当前流中所有元素所产生的结果连接到一起而获得的
(注意,这里每一个结果都是一个流)

 Stream flatMap(Funciton< ? super T , ? extends Stream > mapper)

1.4 抽取子流和组合流

1.调用stream.limit(n)会返回一个新的流,它在n个元素后结束(如果原来的流比n短,那么就会在该流结束时结束)(括号内填的大小小于整体流的大小时跳出)这个方法对于裁剪无限流的尺寸时特别有用

Stream randoms = Stream.generate(Math::random).limit(100);
//会产生一个包含100个随机数的流

2.调用`stream.skip(n)`正好相反,它会丢弃前`n`个元素,因为按照`split`的工作方式,假如第一个元素无用:
Stream words = Stream.of(contents.split("//PL+")).skip(1);
//第一个元素无用时,跳过

3.stream.takeWhile(predicate)调用会在谓词 (参数) 为真true时获取流中所有元素后停止
假如使用上一部分的codePoints方法分割字符并收集;(整体和if有点相似,为true则存入)

Stream initialDigits = codePoints(str).takeWhile(s ->"0...9".contain(s));
//开头包含0...9的

stream.dropWhile(predicate)则正好相反,条件为true时丢弃元素.

Stream withoutInitialWhiteSpace = codePoints(str).dropWhile(s -> s.trim().length=0)
//开头为空格的,通过trim进行获取

4.可以用静态`concat`方法将两个流拼接
Stream combined = Stream.concat(codePoints("Hello"),codePoints("World"));

输出则为:["H","e","l","l","o","W","o","r","l","d"] codePoints方法在1.3部分内.


抽取子流和组合流总结
Stream limit(long maxSize);//产生一个流,其中包含了括号内最初的元素个数
Stream skip(long n);		  //产生一个流,包含除了条件内的元素个数外的所有元素
============================================================================
Stream takeWhile(Predicate predicate);
//产生一个流,包含所有满足条件的元素
Stream dropWhile(Predicate predicate);
//产生一个流,排除不满足谓词(参数)条件的元素之外的所有元素
============================================================================
static  Stream concat(Stream a , Stream b)
//产生一个流,它的元素是a的元素后面跟着b的元素(和一般所知的concat基本一致,不过是关于流的拼接)
结尾

以上为Java8的流库的部分特性以及示例,还没有总结完毕,后续会保持该文章持续更新。
本文多为OGtwelve学习高级特性时所总结,创作不易,点个赞点个收藏都万分感谢哦
文章与OGtwelve个人网站www.ogtwelve.com.cn保持同步更新,再次感谢大家的点赞收藏;
在未来的日子里要和各位一起熠熠生辉 Share & Learn !

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/665824.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号