JDK8-第三章:Stream的使用

StreamAPl说明

●Java8中有两大最为重要的改变。第-一个是Lambda表达式:另外一个则
是Stream API。
●Stream API ( java. util.stream)把真正的函数式编程风格引入到Java中。这
是目前为止对Java类库最好的补充,因为Stream API可以极大提供Java程
序员的生产力,让程序员写出高效率、干净、简洁的代码。
●Stream 是Java8中处理集合的关键抽象概念,它可以指定你希望对集合进
行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用
Stream API对集合数据进行操作,就类似于使用SQL执行的数据库查询。
也可以使用Stream API来并行执行操作。简言之,StreamAPl 提供了一种
高效且易于使用的处理数据的方式。

●实际开发中,项目中多数数据源都来自于Mysq|l, Oracle等。 但现在数
据源可以更多了,有MongDB,Radis等, 而这些NoSQL的数据就需要
Java层面去处理。
●Stream 和Collection集合的区别: Collection 是一种静态的内存数据
结构,而Stream是有关计算的。前者是主要面向内存,存储在内存中,
后者主要是面向CPU,通过CPU实现计算。

Stream到底是什么呢?

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

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

在这里插入图片描述

使用

  1. Stream关注的是对数据的运算,与CPU打交道
    集合关注的是数据的存储,与内存打交道
    2.aStream自己不会存储元素。
    Stream不会改变源对象。相反,他们会返回-个持有结果的新Stream。
    Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行
    3.Stream执行流程
    ①Stream的实例化
    ②一系列的中间操作(过滤、映射、…)
    ③终止操佾
    4.说明:
    4.1一个中间操作链,对数据源的数据进行处理
    4.2 - -旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用
package com.changxiong.StreamTest;

import java.util.Objects;

/**
 * @author changxiong
 * @create 2020-12-14-11:18 PM
 */
public class Employee {
    private String id;
    private String name;
    private Integer age;
    private Integer salary;

    public Employee() {
    }

    public Employee(String id) {
        this.id = id;
    }

    public Employee(String id, String name) {
        this.id = id;
        this.name = name;
    }

    public Employee(String id, String name, Integer age, Integer salary) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getSalary() {
        return salary;
    }

    public void setSalary(Integer salary) {
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Employee employee = (Employee) o;
        return Objects.equals(id, employee.id) &&
                Objects.equals(name, employee.name) &&
                Objects.equals(age, employee.age) &&
                Objects.equals(salary, employee.salary);
    }

    @Override
    public int hashCode() {

        return Objects.hash(id, name, age, salary);
    }
}

package com.changxiong.StreamTest;

import java.util.ArrayList;
import java.util.List;

/**
 * @author changxiong
 * @create 2020-12-15-2:41 PM
 */
public class EmployeeData {
    public static List<Employee> getEmployees() {
        List<Employee> list = new ArrayList<>();

        list.add(new Employee("1001","小明",40,100));
        list.add(new Employee("1002","小白",50,101));
        list.add(new Employee("1003","小黑",60,102));
        list.add(new Employee("1004","虎妹",70,103));
        list.add(new Employee("1005","卡喵",80,104));
        list.add(new Employee("1006","花花",90,105));
        list.add(new Employee("1007","小咕噜",120,106));
        list.add(new Employee("1008","小憨包",130,107));
        list.add(new Employee("1009","白居居",140,109));

        return list;
    }
}

package com.changxiong.StreamTest;

import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @author changxiong
 * @create 2020-12-15-2:51 PM
 */
public class StreamDemo {

    /**
     * 创建Stream方式二: 通过数组。
     * Java8中的Arrays的静态方法stream()可以获取数组流:
     * ●static <T> Stream<T> stream(T0 array):返回-一个流
     * 重载形式,能够处理对应基本类型的数组:
     * ●public static IntStream stream(int[] array)
     * ●public static LongStream stream(longD array)
     * ●public static DoubleStream stream(double[] array)
     */
    @Test
    public void test1() {
        List<Employee> list = EmployeeData.getEmployees();
        //创建一个顺序流
        Stream<Employee> stream = list.stream();

        //创建一个并行流
        Stream<Employee> listParallel = list.parallelStream();

    }

    @Test
    public void test2() {
        int[] arr=new int[]{1,2,3,4,5,6};

        IntStream stream = Arrays.stream(arr);

        Employee e1 = new Employee("1001", "Tom");
        Employee e2 = new Employee("1002", "Mery");

        Employee[] arr1=new Employee[]{e1,e2};
        Stream<Employee> stream1 = Arrays.stream(arr1);
    }

    /**
     * 。创建Stream方式三:通过Stream的of()
     * 可以调用Stream类静态方法of(),通过显示值创建-一个
     * 流。它可以接收任意数量的参数。
     * ●public static<T> Stream<T> of(T.. values):返回一个流
     */
    @Test
    public void test3() {
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6);

        Stream<String> s = Stream.of("a", "b", "c");
    }

    @Test
    public void test4() {
        //迭代
        // public static <T>Stream<Integer> iterate(Integer seed, UnaryOperator<Integer> f)
        // unaryOperator 传入一个类型,返回一个同类型的值
        Stream.iterate(0,t->t+2).limit(10).forEach(System.out::println);

        System.out.println();

        //生成
        //public static <T> Stream<T> generate(@NotNull java.util.function.Supplier<T> s)
        Stream.generate(Math::random).limit(10).forEach(System.out::println);
    }

    //====================================Stream的中间件==============================

    /**
     * Stream的中间操作。
     * 多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止
     * 操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全
     * 部处理,称为“惰性求值”
     * 1-筛选与切片
     * 方法
     * 描述
     * filter(Predicate p)
     * 接收Lambda,从流中排除某些元素
     * distinct()
     * 筛选,通过流所生成元素的hashCode()和equals()去除重复元素
     * limit(long maxSize)截断流, 使其元素不超过给定数量
     * 跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一
     * skip(long n)
     * 个空流。与limit(n)互补
     */
    @Test
    public void test5() {
        //filter(redicate p)排除某些元素
        List<Employee> employees = EmployeeData.getEmployees();
        Stream<Employee> stream = employees.stream();

        stream.filter(e->e.getAge()>50).forEach(e-> System.out.println(e.getName()));

        System.out.println("============");

        //limit(n) 截断流 元素不超过指定个数
        employees.stream().limit(10).forEach(e-> System.out.println(e.getName()));
        System.out.println();

        //skip 跳过元素
        employees.stream().skip(3).forEach(System.out::println);
        System.out.println();
        //distinct 去重 需要重写对象的hashCode和equal方法才能去重
        employees.add(new Employee("1012","虎妹",40,100));
        employees.add(new Employee("1012","虎妹",40,100));
        employees.add(new Employee("1012","虎妹",40,100));
        employees.add(new Employee("1012","虎妹",40,100));
        employees.add(new Employee("1012","虎妹",40,100));
        employees.add(new Employee("1012","虎妹",40,100));

        employees.stream().distinct().forEach(System.out::println);

    }

    //=========================================中间操作 之 映射========================================
    @Test
    public void test6() {
        //map(Function)
        List<String> list = Arrays.asList("aa", "bb", "cc", "dd");

        list.stream().map(s->s.toUpperCase()).forEach(System.out::println);

        System.out.println();

        //获取员工名称长度为3的员工
        List<Employee> employees = EmployeeData.getEmployees();
        Stream<String> streamMap = employees.stream().map(Employee::getName);
        streamMap.filter(s->s.length()>=3).forEach(System.out::println);

        //练习
        Stream<Stream<Character>> streamStream = list.stream().map(StreamDemo::fromToString);
        streamStream.forEach(s->s.forEach(System.out::println));

        System.out.println();

        Stream<Character> characterStream = list.stream().flatMap(StreamDemo::fromToString);
        characterStream.forEach(System.out::println);

    }

    public static Stream<Character> fromToString(String str) {
        ArrayList<Character> list = new ArrayList<>();
        char[] chars = str.toCharArray();
        for (char aChar : chars) {
            list.add(aChar);
        }

        return list.stream();
    }

    //=========================================中间操作 之 排序========================================

    @Test
    public void test7() {
        List<Integer> list = Arrays.asList(10, 23, 45, 23, 28, 84, 9, 10, 83, 45);
        list.stream().sorted().forEach(System.out::println);

        List<Employee> employees = EmployeeData.getEmployees();
        employees.stream().sorted((e1,e2)->Integer.compare(e1.getAge(),e2.getAge()))
                .forEach(System.out::println);

        System.out.println();

        employees.stream().sorted(
                (e1,e2)->{
                    int ageValue = Integer.compare(e1.getAge(), e2.getAge());
                    if (ageValue!=0){
                        return ageValue;
                    }else{
                        int salaryValue = Integer.compare(e1.getSalary(), e2.getSalary());
                        return salaryValue;
                    }
                }
        ).forEach(System.out::println);
    }

    //===============Stream终止符===================
    @Test
    public void test8() {
        //是否匹配所有元素 allmatch(predicate p)
        //是否所有员工年龄都大于18
        List<Employee> employees = EmployeeData.getEmployees();
        boolean b = employees.stream().allMatch(e -> e.getAge() > 18);
        System.out.println(b);

        System.out.println();

        //anyMath(predicate p )至少匹配一个
        boolean b1 = employees.stream().anyMatch(e -> e.getAge() > 18);
        System.out.println(b1);

        System.out.println();

        //noneMatch(predicate p) 没有匹配的
        boolean b2 = employees.stream().noneMatch(e -> e.getAge() > 10);
        System.out.println(b2);

        System.out.println();

    }

    @Test
    public void test9() {
        List<Employee> employees = EmployeeData.getEmployees();

        //返回第一个元素 findFirst
        Optional<Employee> employee = employees.stream().findFirst();
        System.out.println(employee);

        System.out.println();

        //返回任意一个对象 findany
        Optional<Employee> any = employees.stream().findAny();
        System.out.println(any);

        System.out.println();

        //返回流中元素统计数量 count
        long count = employees.stream().filter(e -> e.getSalary() > 100).count();
        System.out.println(count);

        System.out.println();

        //max(comparator c) 返回流中元素最大值
         //返回员工工资最高的
        Stream<Integer> salaryStream = employees.stream().map(e -> e.getSalary());
        Optional<Integer> max = salaryStream.max(Double::compare);
        System.out.println(max);

        System.out.println();
        //min(comparator c)返回流中最小值 返回年龄最小的
        Stream<Integer> ageStream = employees.stream().map(e -> e.getAge());
        Optional<Integer> min = ageStream.min(Integer::compare);
        System.out.println(min);

        System.out.println();
        //foreach 内部遍历
        employees.stream().forEach(e-> System.out.println(e.toString()));
    }

    //--------------终止 之 规约----------------------
    @Test
    public void test10() {
        //reduce(T identify,BinaryOperator p) 归约 将流中的值反复结合起来得到一个值
        //第一个参数是传入的参数 第二个是function的子类
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 5, 6, 7, 8, 9);
        Integer max = list.stream().reduce(0, Integer::sum);
        System.out.println(max);

        System.out.println();

        //reduce(binaryoperator)
        //计算员工工资总和
        Stream<Integer> integerStream = EmployeeData.getEmployees().stream().map(e -> e.getSalary());
        Optional<Integer> reduce = integerStream.reduce(Integer::sum);
        System.out.println(reduce);
    }

    //================终止操作 之 收集
    @Test
    public void test11() {
        //collect(collector c)
        //查找工资大于103 返回一个list或者set集合
        List<Employee> collect = EmployeeData.getEmployees().stream().filter(e -> e.getSalary() > 103).collect(Collectors.toList());
        collect.forEach(System.out::println);

        System.out.println();

        Set<Employee> collect1 = EmployeeData.getEmployees().stream().filter(e -> e.getSalary() > 103).collect(Collectors.toSet());
        collect1.forEach(System.out::println);
    }

}

在这里插入图片描述
排序
在这里插入图片描述
终止

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值