天天看点

java Stream的学习与简单练习java Stream的学习与简单练习

java Stream的学习与简单练习

什么是stream

  • Stream 流是java 1.8 的新特性之一。
  • stream 是处理 :集合、数组、IO流等数据的抽象概念,简单来说就是处理数据。并返回一个新的流(不修改原有的数据,而是讲处理后的的数据放在另一个流中 – 惰性操作)。最后以终止操作结尾。

Stream 与 Collection 流和集合的区别

  • 没有存储。流不是存储元素的数据结构;相反,它通过计算操作的管道传送来自数据结构、数组、生成器函数或 I/O 通道等源的元素。
  • 对流的操作会产生结果,但不会修改其源
  • 许多流操作,例如过滤、映射或重复删除,可以懒惰地实现
  • 集合有大小的限制,而流没有
  • 流中的元素在流的生命周期中只会被访问一次

获得流的方式

  • 从一个Collection通过stream()和 parallelStream()方法
  • 从一个数组通过Arrays.stream(Object[])
  • 流类上的静态工厂方法 Stream.of(Object[]) 或 Stream.iterate(Object, UnaryOperator)
  • 文件的lines() BufferedReader.lines();
  • 可以从以下位置获得随机数流Random.ints();
  • ……

流的操作和管道

  • 流操作分为中间操作和 终端操作,结合起来形成流管道。一个流管道由一个源(例如一个 Collection、一个数组、一个生成器函数或一个 I/O 通道)组成;后跟零个或多个中间操作,例如 Stream.filter或Stream.map;和终端操作,例如Stream.forEach或Stream.reduce
  • 中间操作返回一个新的流。执行中间操作,例如 filter()实际上并不执行任何过滤,而是创建一个新流,该流在遍历时包含与给定谓词匹配的初始流的元素。管道源的遍历直到管道的终端操作被执行后才开始。
  • 有状态:指元素的处理不受之前元素的影响。如:filter and map(过滤和映射 惰性操作)
  • 无状态:指操作只有拿到所有元素之后才能继续下去。如:distinct和sorted(去重和排序)
  • 并行性:jdk默认串行,也可以在初始创建流时选在串行还是并行。如Collection有方法 Collection.stream()和Collection.parallelStream()

Stream 简单操作示例(一下示例以常用的集合为例)

  • 代码一

/**			过滤空字符串  、计算空字符的个数
         * stream().filter(过滤的条件) 过滤
         * String -> !String.isempty  过滤不为空的字符
         * collect(Collectors.toList()) 将过滤好的数据专入集合
         * collect(Collectors.joining(",")) 用逗号拼字符集合数据并转为String类型
         */
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
//过滤空字符串
List<String> filterStrings = strings.stream()
									.filter(String -> !String.isEmpty()) 
									.collect(Collectors.toList());
//空字符串的个数
 long count = strings.stream().filter(String -> String.isEmpty()).count();
 //用逗号拼接的字符串
 String str = strings.stream()
 					.filter(s -> !s.isEmpty())
 					.collect(Collectors.joining(","));
  System.out.println("用逗号拼接的字符串:"+str);
  System.out.println("空字符串的个数 "+count);
  System.out.println("不为空的字符串集合: "+filterStrings); 					
           
  • 运行结果
用逗号拼接的字符串:abc,bc,efg,abcd,jkl
空字符串的个数 2
不为空的字符串集合: [abc, bc, efg, abcd, jkl]
           

代码二

/**
  *  stream().map :映射集合中每个元素对用的结果
  *  i-> i+10 :  i 代表集合中的每个元素  -> :映射处理转换数据i  i+10 : 每个元素i 结果
  *  collect(Collectors.toList())将处理好的元素存入集合
  *  nums.forEach(System.out :: println); forEach 遍历nums 整形集合
*/
  List<Integer> nums = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
 // 遍历nums 集合
 nums.forEach(System.out :: println);
 //将集合中的每个元素都+10
 List<Integer> mapNums = nums.stream()
 							 .map(i -> i+10)
 							 .collect(Collectors.toList());
System.out.println(mapNums);
//也可以先过滤在映射
List<Integer> numOne = nums.stream()
						   .filter(i -> i<=2 )
						   .map(i -> i*i)
						   .collect(Collectors.toList());
numOne.forEach(System.out::println);
           
  • 运行结果
3
2
2
3
7
3
5

[13, 12, 12, 13, 17, 13, 15]

4
4
           

代码三

/**
   * mapToInt((s) -> Integer.valueOf(s)) 讲stringNums 中的string类型数据转为int
   * summaryStatistics() 返回一个状态对象,用于收集计数、最小值、最大值、总和和平均值等统计信息。
   */
List<String> stringNums = Arrays.asList("3", "2", "2", "3", "7", "3", "5");
IntSummaryStatistics statistics = stringNums.stream().mapToInt((s) -> Integer.valueOf(s)).summaryStatistics();
System.out.println(statistics.getCount());;
System.out.println("max: "+statistics.getMax());
System.out.println("min: "+statistics.getMin());
System.out.println("sum: "+statistics.getSum());
System.out.println("Class: "+statistics.getClass());
System.out.println("avg: "+statistics.getAverage());
           
  • 运行结果
count: 7
max: 7
min: 2
sum: 25
Class: class java.util.IntSummaryStatistics
avg: 3.5714285714285716