Java8新特性之Stream流式编程----附API应用实例

一.Stream介绍

  • Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据
  • Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象
  • Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果

+--------------------+       +------+   +------+   +---+   +-------+
| stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect|
+--------------------+       +------+   +------+   +---+   +-------+

二.什么是Stream

Stream(流)是一个来自数据源的元素队列并支持聚合操作

  • 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算
  • 数据源:流的来源。 可以是集合,数组,I/O channel, 产生器generator 等
  • 聚合操作:类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等

Stream操作还有两个基础的特征:

  • Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)
  • 内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现

三.Stream的操作步骤

在这里插入图片描述
Stream的使用需要经过三个步骤,创建,中间操作,结果


1.创建Stream

		//1.通过Collection接口的Stream()方法
 		List<String> list = Arrays.asList("1","2","3","4","0","222","33");
        Stream<String> stream = list.stream();
		Stream<String> stream1 = list.parallelStream();

		//2.通过Arrays中的静态方法stream()获取数组流
		IntStream stream = Arrays.stream(new int[]{1,2,3});

 		//3.通过Stream类中的 of()静态方法获取流
 		Stream<String> stream = Stream.of("a","b","c");


		//4.无限流
		//迭代(需要传入一个种子,也就是起始值,然后传入一个一元操作)
     	Stream<Integer> stream1 = Stream.iterate(2, (x) -> x * 2);

     	//生成(无限产生对象)
     	Stream<Double> stream2 = Stream.generate(() -> Math.random());



2.Stream的中间操作

多个中间操作可以连接起来形成一个流水线,除非流水 线上触发终止操作,否则中间操作不会执行任何的处理! 而在终止操作时一次性全部处理,称为惰性求值

一.筛选与切片
在这里插入图片描述

代码示例:

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 获取空字符串的数量
long count = strings.stream().filter(string -> string.isEmpty()).count();

filter方法传入一个Predicate,获得空字符串数量

Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

limit指定流的数量


二.映射

在这里插入图片描述

map 方法用于映射每个元素到对应的结果,以下代码片段使用 map 输出了元素对应的平方数:

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
// 获取对应的平方数
List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());

三.排序
在这里插入图片描述
sorted 方法用于对流进行排序。以下代码片段使用 sorted 方法对输出的 10 个随机数进行排序:

Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);

3.Stream的终止操作

终止操作分为三种,查找匹配,归约,和收集

查找与匹配:检查是否匹配某种断言,或者返回某些元素
在这里插入图片描述

归约
在这里插入图片描述
备注:map 和reduce 的连接通常称为map-reduce 模式,因Google 用它 来进行网络搜索而出名

收集:这个很常用,就是把操作做完的元素收集到某个对象中

在这里插入图片描述


四.StreamAPI应用实例


	/*
	  	1.	给定一个数字列表,如何返回一个由每个数的平方构成的列表呢?
		,给定【1,2,3,4,5】, 应该返回【1,4,9,16,25】。
	 */
	@Test
	public void test1(){
		Integer[] nums = new Integer[]{1,2,3,4,5};
		
		Arrays.stream(nums)
			  .map((x) -> x * x)
			  .forEach(System.out::println);
	}

使用了Arrays类来构造stream,使用了map对每一个元素进行映射,最后使用forEach终止操作输出。


/*
	 2.	怎样用 map 和 reduce 方法数一数流中有多少个Employee呢?
	 */
	List<Employee> emps = Arrays.asList(
			new Employee(102, "李四", 59, 6666.66, Status.BUSY),
			new Employee(101, "张三", 18, 9999.99, Status.FREE),
			new Employee(103, "王五", 28, 3333.33, Status.VOCATION),
			new Employee(104, "赵六", 8, 7777.77, Status.BUSY),
			new Employee(104, "赵六", 8, 7777.77, Status.FREE),
			new Employee(104, "赵六", 8, 7777.77, Status.FREE),
			new Employee(105, "田七", 38, 5555.55, Status.BUSY)
	);
	
	@Test
	public void test2(){
		Optional<Integer> count = emps.stream()
			.map((e) -> 1)
			.reduce(Integer::sum);
		
		System.out.println(count.get());
	}
发布了74 篇原创文章 · 获赞 4 · 访问量 2485
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章