Java Stream.of()和IntStream.range()用法及区别
发布时间:2025-05-24 02:42:06 发布人:远客网络
一、Java Stream.of()和IntStream.range()用法及区别
1、Stream.of()方法用于创建一个不可修改的流,其中包含指定的对象。例如:
2、Stream.of("Apple","Banana","Cherry");
3、这将创建一个包含"Apple"、"Banana"和"Cherry"字符串的流。这个流可以用于执行各种操作,如过滤、映射、收集等。
4、IntStream.range()方法用于创建一个包含指定范围内的整数流。例如:
5、这将创建一个包含从1到4的整数流。这个流可以用于执行各种数学运算,如求和、计算平均值、遍历元素等。
6、Stream.of()和IntStream.range()的区别在于它们创建的流类型不同。Stream.of()用于创建包含对象的流,而IntStream.range()用于创建包含整数的流。此外,Stream.of()创建的流是不可修改的,而IntStream.range()创建的流是可修改的。
7、在实际应用中,Stream.of()通常用于创建包含常量或静态数据的流,而IntStream.range()则用于执行需要整数范围的计算或操作。例如,在处理数组、集合或列表等数据结构时,可以使用Stream.of()对数据进行操作;而在执行数学计算、生成序列等任务时,可以使用IntStream.range()。
8、总之,Stream.of()和IntStream.range()都是Java中非常有用的方法,它们分别用于创建不同类型的流。理解它们的使用场景和区别,可以帮助开发者更有效地利用Java的流功能进行数据处理和计算。
二、用Java 8 增加的 Stream API 能实现哪些优雅的算法
1、Java 8引入了全新的Stream API。这里的Stream和I/O流不同,它更像具有Iterable的集合类,但行为和集合类又有所不同。
2、Stream API引入的目的在于弥补Java函数式编程的缺陷。对于很多支持函数式编程的语言,map()、reduce()基本上都内置到语言的标准库中了,不过,Java 8的Stream API总体来讲仍然是非常完善和强大,足以用很少的代码完成许多复杂的功能。
3、创建一个Stream有很多方法,最简单的方法是把一个Collection变成Stream。我们来看最基本的几个操作:
4、public static void main(String[] args){
5、List<Integer> numbers= Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
6、Stream<Integer> stream= numbers.stream();
7、}).forEach(System.out::println);
8、集合类新增的stream()方法用于把一个集合变成Stream,然后,通过filter()、map()等实现Stream的变换。Stream还有一个forEach()来完成每个元素的迭代。
9、为什么不在集合类实现这些操作,而是定义了全新的Stream API?Oracle官方给出了几个重要原因:
10、一是集合类持有的所有元素都是存储在内存中的,非常巨大的集合类会占用大量的内存,而Stream的元素却是在访问的时候才被计算出来,这种“延迟计算”的特性有点类似Clojure的lazy-seq,占用内存很少。
11、二是集合类的迭代逻辑是调用者负责,通常是for循环,而Stream的迭代是隐含在对Stream的各种操作中,例如map()。
12、要理解“延迟计算”,不妨创建一个无穷大小的Stream。
13、如果要表示自然数集合,显然用集合类是不可能实现的,因为自然数有无穷多个。但是Stream可以做到。
14、自然数集合的规则非常简单,每个元素都是前一个元素的值+1,因此,自然数发生器用代码实现如下:
15、class NaturalSupplier implements Supplier<Long>{
16、反复调用get(),将得到一个无穷数列,利用这个Supplier,可以创建一个无穷的Stream:
17、public static void main(String[] args){
18、Stream<Long> natural= Stream.generate(new NaturalSupplier());
19、}).limit(10).forEach(System.out::println);
20、对这个Stream做任何map()、filter()等操作都是完全可以的,这说明Stream API对Stream进行转换并生成一个新的Stream并非实时计算,而是做了延迟计算。
21、当然,对这个无穷的Stream不能直接调用forEach(),这样会无限打印下去。但是我们可以利用limit()变换,把这个无穷Stream变换为有限的Stream。
22、利用Stream API,可以设计更加简单的数据接口。例如,生成斐波那契数列,完全可以用一个无穷流表示(受限Java的long型大小,可以改为BigInteger):
23、class FibonacciSupplier implements Supplier<Long>{
24、public static void main(String[] args){
25、Stream<Long> fibonacci= Stream.generate(new FibonacciSupplier());
26、fibonacci.limit(10).forEach(System.out::println);
27、如果想取得数列的前10项,用limit(10),如果想取得数列的第20~30项,用:
28、List<Long> list= fibonacci.skip(20).limit(10).collect(Collectors.toList());
29、最后通过collect()方法把Stream变为List。该List存储的所有元素就已经是计算出的确定的元素了。
30、用Stream表示Fibonacci数列,其接口比任何其他接口定义都要来得简单灵活并且高效。
三、【Java必修课】图说Stream中的skip()和limit()方法及组合使用
1、本文将讲解Java 8 Stream中的两个方法:skip()和limit()。这两个方法是Stream很常用的,不仅各自会被高频使用,还可以组合出现,并能实现一些小功能,如subList和分页等。
2、skip()方法用于跳过前面n个元素,然后再返回新的流。方法skip()的参数n的四种情况是:(1)当n<0时,抛IllegalArgumentException异常;(2)当n=0时,相当没有跳过任何元素,原封不动、完璧归赵;(3)当0<n<length时,跳过前n个元素;(4)当n>=length时,跳过所有元素,返回空流。
3、limit()方法用于限制流中元素的个数,即取前n个元素,返回新的流。方法limit()的参数n的四种情况是:(1)当n<0时,抛IllegalArgumentException异常;(2)当n=0时,不取元素,返回空流;(3)当0<n<length时,取前n个元素;(4)当n>=length时,取所有元素,原封不动、完璧归赵。
4、对于无限流,skip()和limit()表现出了极大的差异。skip()则不行,不管你跳过了前面多少个元素,总还是会有源源不断的元素过来,无法收敛。而limit()是可以将无限流转化为有限流的,所以我们也可以认为它是一个短路操作。
5、除了两者各自有各自的功能外,我们通过组合使用,可以实现其它功能。例如,可以将集合类如List的subList()方法转换为skip(startIndex).limit(endIndex- startIndex)。还可以通过组合使用skip()和limit()进行分页。
6、在组合应用中,需要注意的是,如果Stream过大或是无限流,小心skip()会有性能问题。
7、Java必修课包括:Java 8 Streams的简单介绍与入门、Java 8基本类型的Stream、如何创建和初始化一个HashMap、Java双大括号{}的初始化、Java 8中map()与flatMap()在Optional和Stream中的区别等。Java实例包括:使用Thumbnailator生成缩略图、统计String单词数的三种方法、使用正则统计英文文章中的高频词汇等。MongoDB相关知识有:用Docker安装一个MongoDB最新版玩玩、2019年MongoDB中文社区广州大会,干货满满的分享活动等。其他领域有:如何使用优秀的加密库Jasypt来保护你的敏感信息、Spring的定时任务注解@Scheduled原来如此简单等。
8、欢迎关注公众号,将持续为你更新更多知识。欢迎加博主微信,做一个点赞之友。多读书,多分享;多写作,多整理。Springboot系列文章有:Springboot整合邮件服务(HTML/附件/模板-QQ、网易)、Springboot整合Jasypt、Springboot Admin监控微服务应用等。