Stream API概述

发布于:2022-12-13 ⋅ 阅读:(1097) ⋅ 点赞:(1)

目录

 一:简单概述

二:什么是流(Stream)

三:Stream API 

四:Stream 的三个操作步骤

五:创建Stream 

六:Stream 的中间操作

七:Stream 的终止操作


 一:简单概述

是Java8的一大亮点,是对容器对象功能的增强,它专注于对容器对象进行各种非常便利、高效的 聚合操作(aggregate operation)或者大批量数据操作。Stream API借助于同样新出现的Lambda表达式,极大的提高编程效率和程序可读性。同时,它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用fork/join并行方式来拆分任务和加速处理过程。所以说,Java8中首次出现的 java.util.stream是一个函数式语言+多核时代综合影响的产物。

二:什么是流(Stream)

1.Stream不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的Iterator。

2.高级版本的Stream,用户只要给出需要对其包含的元素执行什么操作即可。

3.Stream可以并行化操作,迭代器只能命令式地、串行化操作。顾名思义,当使用串行方式去遍历时,每个item读完后再读下一个item。而使用并行去遍历时,数据会被分成多个段,其中每一个都在不同的线程中处理,然后将结果一起输出

4. Stream 的另外一大特点是,数据源本身可以是无限的。

5.流(Stream)是数据渠道,用于操作数据(数组,集合等)所生成的元素序列。

6.集合讲的是数据,流讲的是计算。

注意:

1.Stream 自己不会存储元素。

2.Stream 不会改变源对象。相反他们会返回一个持有结果的新Stream。

3.Stream 操作时延迟执行的。这意味着他们会等到需要结果的时候才会执行。

三:Stream API 

1.使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用,Stream API 来并行执行操作。

2.简而言之,就是Stresm API 提供了一种高效且易于使用的处理数据的方式。

四:Stream 的三个操作步骤

        1.创建 Stream 

           一个数据源,(如:集合,数组),获取一个数据源。

        2.中间操作

            一个中间操作链,对数据源的数据进行处理。

        3.终止操作(终端操作)

            一个终止操作,执行中间操作链 ,并产生结果。

五:创建Stream 

/**
 *
 * 一、Stream 的三个操作步骤
 * 1、 创建Stream
 * 2、 中间操作
 * 3、 终止操作
 */
public class TestStreamAPI01 {
    @Test
    public void test01 (){
        //1.可以通过Collection 系列集合提供的 stream() 或者 parallelStream()
        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.forEach(System.out::println);
            //stream4.limit(10).forEach(System.out::println);
            //生成
            Stream<Double> generate = Stream.generate(() -> (Math.random()*10));
            generate.limit(10).forEach(System.out::println);
    }
}

六:Stream 的中间操作

/**
 * @author 浩楠
 * @version 1.0.0
 * 2022/9/15 上午10:52 2022
 */
public class TestStreamAPI02 {
    List<Employee> employees = Arrays.asList(
            new Employee(1,"张三",18,9999.9),
            new Employee(2,"李四",58,5555.5),
            new Employee(3,"王五",26,3333.3),
            new Employee(4,"赵六",36,6666.6),
            new Employee(5,"田七",12,8888.8),
            new Employee(6,"田七",12,8888.8)
            );
    //一系列的中间操作
    /**
     * 筛选与切片
     * filter--接受lambda表达式,从流中排除某些元素
     * limit --截断流,使其元素不超过给定数量
     * skip(n)--跳过元素,返回一个扔掉了前n个元素的了流,若流中的元素不足n个,就返回一个空流,与limit互补。
     * distinct--筛选,通过流所生成的hashcode() 和 equals() 去重元素。
     */
    //内部迭代:迭代操作 有Stream API 完成。
    @Test
    public void test01 (){
        Stream<Employee> stream1 = employees.stream();
        Stream<Employee> stream2 = stream1.filter((e) -> e.getAge() > 35);
        stream2.forEach(System.out::println);
    }
    //外部迭代:
    @Test
    public void test02 (){
        Iterator<Employee> it = employees.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
    @Test
    public void test03 (){
        employees.stream()
                .filter((e) -> e.getIncome()>5000)
                .limit(2)
                .forEach(System.out::println);
    }
    @Test
    public void test04 (){
        employees.stream()
                .filter((e) -> e.getIncome()>5000)
                .skip(2)
                .distinct()
                .forEach(System.out::println);
    }


    /**
     * 映射
     * map--接受 Lambda,将元素转换成其他形式或者提取信息。接受一个函数作为参数,该函数会被应用到每一个
     * 元素上,并将其映射成一个新的元素。
     * flatMap --接收一个函数作为参数,将流中的每一个值转换成一个新的流。
     */
    @Test
    public void test05 () {
        List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
        list.stream()
                .map((str) -> str.toUpperCase())
                .forEach(System.out::println);
        employees.stream()
                .map(Employee::getNickname)
                .forEach(System.out::println);
    }

    /**
     * 排序
     * sorted()--自然排序(Comparable)
     * sorted(Comparator com )--定制排序(Comparator)
     */
    @Test
    public void test06 (){
        List<String> list = Arrays.asList("cc","aa","bb","dd","ee");
        list.stream()
                .sorted()
                .forEach(System.out::println);
        System.out.println("---------------------");
        employees.stream()
                .sorted((e1,e2) -> {
                    if (e1.getAge().equals(e2.getAge())) {
                        return e1.getNickname().compareTo(e2.getNickname());
                    }else{
                        return -e1.getAge().compareTo(e2.getAge());
                    }
                }).forEach(System.out::println);
    }
}

七:Stream 的终止操作

public class TestStreamAPI3 {
	
	List<Employee> emps = Arrays.asList(
			new Employee(102, "李四", 79, 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)
	);
	
	//3. 终止操作
	/*
		归约
		reduce(T identity, BinaryOperator) / reduce(BinaryOperator) ——可以将流中元素反复结合起来,得到一个值。
	 */
	@Test
	public void test1(){
		List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
		
		Integer sum = list.stream()
			.reduce(0, (x, y) -> x + y);
		
		System.out.println(sum);
		
		System.out.println("----------------------------------------");
		
		Optional<Double> op = emps.stream()
			.map(Employee::getSalary)
			.reduce(Double::sum);
		
		System.out.println(op.get());
	}
	
	//需求:搜索名字中 “六” 出现的次数
	@Test
	public void test2(){
		Optional<Integer> sum = emps.stream()
			.map(Employee::getName)
			.flatMap(TestStreamAPI1::filterCharacter)
			.map((ch) -> {
				if(ch.equals('六'))
					return 1;
				else 
					return 0;
			}).reduce(Integer::sum);
		
		System.out.println(sum.get());
	}
	
	//collect——将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法
	@Test
	public void test3(){
		List<String> list = emps.stream()
			.map(Employee::getName)
			.collect(Collectors.toList());
		
		list.forEach(System.out::println);
		
		System.out.println("----------------------------------");
		
		Set<String> set = emps.stream()
			.map(Employee::getName)
			.collect(Collectors.toSet());
		
		set.forEach(System.out::println);

		System.out.println("----------------------------------");
		
		HashSet<String> hs = emps.stream()
			.map(Employee::getName)
			.collect(Collectors.toCollection(HashSet::new));
		
		hs.forEach(System.out::println);
	}
	
	@Test
	public void test4(){
		Optional<Double> max = emps.stream()
			.map(Employee::getSalary)
			.collect(Collectors.maxBy(Double::compare));
		
		System.out.println(max.get());
		
		Optional<Employee> op = emps.stream()
			.collect(Collectors.minBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
		
		System.out.println(op.get());
		
		Double sum = emps.stream()
			.collect(Collectors.summingDouble(Employee::getSalary));
		
		System.out.println(sum);
		
		Double avg = emps.stream()
			.collect(Collectors.averagingDouble(Employee::getSalary));
		
		System.out.println(avg);
		
		Long count = emps.stream()
			.collect(Collectors.counting());
		
		System.out.println(count);
		
		System.out.println("--------------------------------------------");
		
		DoubleSummaryStatistics dss = emps.stream()
			.collect(Collectors.summarizingDouble(Employee::getSalary));
		
		System.out.println(dss.getMax());
	}
	
	//分组
	@Test
	public void test5(){
		Map<Status, List<Employee>> map = emps.stream()
			.collect(Collectors.groupingBy(Employee::getStatus));
		
		System.out.println(map);
	}
	
	//多级分组
	@Test
	public void test6(){
		Map<Status, Map<String, List<Employee>>> map = emps.stream()
			.collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {
				if(e.getAge() >= 60)
					return "老年";
				else if(e.getAge() >= 35)
					return "中年";
				else
					return "成年";
			})));
		
		System.out.println(map);
	}
	
	//分区
	@Test
	public void test7(){
		Map<Boolean, List<Employee>> map = emps.stream()
			.collect(Collectors.partitioningBy((e) -> e.getSalary() >= 5000));
		
		System.out.println(map);
	}
	
	//
	@Test
	public void test8(){
		String str = emps.stream()
			.map(Employee::getName)
			.collect(Collectors.joining("," , "----", "----"));
		
		System.out.println(str);
	}
	
	@Test
	public void test9(){
		Optional<Double> sum = emps.stream()
			.map(Employee::getSalary)
			.collect(Collectors.reducing(Double::sum));
		
		System.out.println(sum.get());
	}
}

本文含有隐藏内容,请 开通VIP 后查看