Steam API


Java 8 中有两大最为重要的改变。第一个是Lambda表达式;另一个则是Stream API(java.util.stream.*).

Stream 是Java8 中处理集合的关键抽象概念,他可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用SQL 执行的数据库查询。也可以使用Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。

什么是Stream

流(Stream)到底是什么呢?
是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。
集合讲的是数据,流讲的是计算!

注意:
①Stream 自己不会存储元素
②Stream 不会改变源对象。相反,他们会返回一个持有结果的新的Stream
③Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

Stream的操作三个步骤

  1. 创建Stream
    一个数据源(如:集合、数组),获取一个流
  2. 中间操作
    一个中间操作链,对数据源的数据进行处理
  3. 终止操作(终端操作)
    一个终止操作,执行中间操作链,并产生结果

在这里插入图片描述

一、创建

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

import org.junit.Test;

import com.it.entity.Employee;

/*
 * 
 * 一、Stream的三个操作步骤
 * 1、创建Stream
 *  
 * 2、中间操作
 * 
 * 3、终止操作(终端操作)
 * 
 */
public class TestStreamAPI1 {

	//创建Stream
	@Test
	public void test1() {
		
		//1、可以通过Collection 系列集合提供的stream()或者 paralleStream() 
		List<String> list = new ArrayList<>();
		Stream<String> stream1 = list.stream();
		
		//2、通过Arrays中的静态方法stream()获取数组流
		Employee[] emps = new Employee[10];
		Stream<Employee> stream2 = Arrays.stream(emps);
		
		
		//3、通过Stream 类中的静态方法of()
		Stream<String> stream3 = Stream.of("aa","bb","cc");
		
		//4、创建无限流
		//迭代
		Stream<Integer> stream4 = Stream.iterate(0,(x) -> x+2);
		stream4.limit(10).forEach(System.out::println);
		
		//生成
		Stream.generate(()-> Math.random())
		.limit(5)
		.forEach(System.out::println);
		
	}
	
}

二、Stream的中间操作

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


static List<Employee> employees = Arrays.asList(

			new Employee("张三",18,9999.99),
			new Employee("李四",38,5555.99),
			new Employee("王五",18,6666.66),
			new Employee("赵六",18,3333.33),
			new Employee("田七",18,7777.77)

			);
	
	//中间操作
	
	/*
	 * 
	 * 筛选与切片
	 * filter -- 接收Lanmbda , 从流中排除某些元素
	 * limit -- 截断流,使其元素不超过给定数量
	 * skip(n) -- 跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流,与limit(n) 互补
	 * distinct -- 筛选,通过Loi所生成的元素的hashCode() 和 equals () 去除重复元素
	 * 
	 */
	//内部迭代
	@Test
	public void test2() {
		//中间操作,不会执行任何操作
		Stream<Employee> stream1 = employees.stream()
		.filter(e->{
			System.out.println("Stream API 的中间操作");
			return e.getAge() > 35;
		});		
		//终止操作:一次性执行全部内容,即"惰性求值"
		stream1.forEach(System.out::println);
	}
	
	//外部迭代
	@Test
	public void test(){
		
		Iterator<Employee> it = employees.iterator();
		
		while(it.hasNext()) {
			System.out.println(it.next());
		}		
	}
	
	@Test
	public void test3() {
		
		employees.stream()
				.filter(e -> e.getSalary() > 5000)
				.limit(2)
				.forEach(System.out::println);		
	}
	
	@Test
	public void test4() {
		
		employees.stream()
		.filter(e -> e.getSalary() > 5000)
		.skip(2)
		.limit(2)
		.forEach(System.out::println);	
	}

重写hsahcode 与 equals 方法

map


	/**
	 * 映射
	 * 
	 * map-- 接收Lambda,将元素转换成其他形式提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
	 * 
	 * flatMap -- 接收一个函数作为参数,将流中的每个值都换成一个流,然后把所有流连成一个流
	 * 
	 */
	@Test
	public void test5() {
		List<String> list = Arrays.asList("aa","bb","cc","dd");
		
		//map
		list.stream().map(String::toUpperCase)
					.forEach(System.out::println);
		
		System.out.println("-------------");
		
		employees.stream()
			.map(emp->emp.getName())
			.forEach(System.out::println);
		
		System.out.println("------flatMap-------");
		
		
		//faltMap 
		Stream<Stream<Character>> stream = list.stream()
					.map(TestStreamAPI1::filterCharacter);
		stream.forEach(System.out::println);    //打印的是流
		
		System.out.println("-------------");
		
		Stream<Character> flatMap = list.stream()
				.flatMap(TestStreamAPI1::filterCharacter);
		flatMap.forEach(System.out::println);           // a,a,b,b,c,c
		
	}
	
	public static Stream<Character> filterCharacter(String str){
		List<Character> list = new ArrayList<>();
		for (Character character : str.toCharArray()) {
			list.add(character);
		}
		return list.stream();
	}
	


排序


	/**
	 * 排序
	 * 
	 * sort() -- 自然排序(Compatable)
	 * 
	 * sort(Comparator com) -- 定制排序(Comparator)  
	 * 
	 */
	@Test
	public void test7() {
		
		List<String> list = Arrays.asList("ccc","bbb","ddd","aaa");
		list.stream()
			.sorted()
			.forEach(System.out::println);  
		
		System.out.println("------------");

		employees.stream()
				.sorted((e1,e2) ->{
					if(e1.getAge() == e2.getAge()) {
						return e1.getName().compareTo(e2.getName());
					}else {
						return Integer.compare(e1.getAge(),e2.getAge());
					}
				}).forEach(System.out::println);
		
	}
	

终止操作


static List<Employee> employees = Arrays.asList(

			new Employee("张三",18,9999.99,Status.FREE),
			new Employee("李四",58,5555.99,Status.BUSY),
			new Employee("王五",26,6666.66,Status.VOCATION),
			new Employee("赵六",36,3333.33,Status.FREE),
			new Employee("田七",12,7777.77,Status.BUSY)

			);
	
	/*
	 * 查找与匹配
	 * 
	 * allMatch -- 检查是否匹配所有元素
	 * anyMatch -- 检查是否至少匹配一个元素
	 * noneMatch -- 检查是否没有匹配所有元素
	 * 
	 * findFirst -- 返回第一个元素
	 * findAny -- 返回当前流中的任意元素
	 * 
	 * count -- 返回流中元素的总个数
	 * max  -- 返回流中的最大值
	 * min -- 返回流中的最小值
	 * 
	 */

	@Test
	public void test1() {
		
		boolean b1 = employees.stream()
		     .allMatch(e->e.getStatus().equals(Status.BUSY));
		
		System.out.println(b1);
		
		
		boolean b2 = employees.stream()
			     .anyMatch(e->e.getStatus().equals(Status.BUSY));
		
		System.out.println(b2);
		
		boolean b3 = employees.stream()
				.noneMatch(e->e.getStatus().equals(Status.BUSY));
		
		System.out.println(b3);
		
		Optional<Employee> op = employees.stream()
				.sorted((e1,e2) -> Double.compare(e1.getSalary(), e2.getSalary()))
				.findFirst();
		
		System.out.println(op.get());
		
		 Optional<Employee> op2 = employees.parallelStream()
			 .filter(e->e.getStatus().equals(Status.BUSY))
			 .findAny();
		 
		 System.out.println(op2.get());
		
	}
	
	@Test
	public  void test2() {
		
		long count = employees.stream()
					.count();
		System.out.println(count);
		
		Optional<Employee> op1 = employees.stream()
				.max((e1,e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
		
		System.out.println(op1.get());
		
		
		Optional<Double> op2 = employees.stream()
		 .map(Employee::getSalary)
		 .min(Double::compareTo);
		
		System.out.println(op2.get());
		
	}

归约

在这里插入图片描述

/*
	 * 
	 * 归约
	 * reduce(T identity,BinatuOperator) / reduce(BinaryOperator)  -- 可以将流中的元素反复结合起来,得到一个值。
	 * 
	 */
	
	@Test
	public void test3() {
		
		List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9);
		
		Integer sum = list.stream()
				.reduce(0,(x,y)-> x+y);
		
		System.out.println(sum);		
		/*

		 开始  x = 0,y = 1
			x =1 ,y=2
			x=3 ,y=3
			x=6 ,y=4
		 	...
		 */				
		Optional<Double> op = employees.stream()
			.map(Employee::getSalary)
			.reduce(Double::sum);	
		System.out.println(op.get());
		
	}
	

收集

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 分组

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

练习

第一题
在这里插入图片描述
第二题 数一数 流中的数量
在这里插入图片描述

第三题
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值