java8 Stream

本文详细介绍了Java8 Stream API的使用,包括如何创建Stream、处理数据(如筛选、映射、排序)以及执行终止操作(如查找、匹配、规约与收集)。通过实例代码展示了Stream的五种创建方法、流处理的各种功能以及并行流的使用,帮助开发者更好地理解和应用Java8的这一核心特性。
摘要由CSDN通过智能技术生成

java8 Stream

概述

steam是java8的新特性,主要是对集合的处理。
一般一个完整的steam语法分为三个步骤

  1. 创建
  2. 处理
  3. 终止条件
//比如
List<Employee> collect = employees.stream().filter((x) -> x.age > 35).collect(Collectors.toList());

接下来用代码实现steam的三个步骤,最后面会把所有用到的代码整体粘贴出来

一、创建

stream流有五种创建方法

public static void createStream() {
        // 1:collection系列
        List<String> srrLIst = new ArrayList<>();
        Stream<String> stream = srrLIst.stream();

        // 2.Arrays
        Integer[] ints = new Integer[10];
        Stream<Integer> stream1 = Arrays.stream(ints);

        // 3.Stream.of
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);

        // 4.无限流 Stream.iterate();
        Stream<Integer> iterate = Stream.iterate(0, x -> x + 2);

        // 5.Stream.generate();
        Stream<Double> generate = Stream.generate(Math::random);
    }

二、处理

流的处理有多种功能

  1. 筛选与切片
    filter:过滤得到符合条件的数据
    limit:拿到结果的前几条
    skip:跳过结果的前几条
    distinct:去重,注意,依靠hashcode,equals 方法去重
    必须得提一句,stream的处理过程都是在终止操作时才执行的,而不是把每一个都元素都直接处理完成再执行终止语句。
    public static void test() {
        // filter
        employees.stream().filter((x) -> x.age > 35).forEach(System.out::println);
        System.out.println("----------------------------------");
        // limit
        employees.stream().filter((x) -> x.salary > 5000)
                .limit(2)
                .forEach(System.out::println);

        System.out.println("----------------------------------");
        // skip
        employees.stream().filter((x) -> x.salary > 5000)
                .skip(2)
                .forEach(System.out::println);

        System.out.println("----------------------------------");
        // distinct
        employees.stream().filter((x) -> x.salary > 5000)
                .distinct()
                .forEach(System.out::println);
    }
  1. 映射
    map: 接受一个函数作为参数,该函数会应用到没一个元素上,并将其映射成一个新的元素
    flatMap: 将流中的每个值都转化为另一个流,并且将所有流连接成一个流。
    public static void testMap() {
        // map
        String[] strArr = {"aaa", "bbb", "ccc", "ddd"};
        Arrays.stream(strArr).map(String::toUpperCase).forEach(System.out::println);
        System.out.println("--------------------------");
        employees.stream().map(Employee::getName).forEach(System.out::println);
        System.out.println("#########################");
        // flatMap
        // 如果只使用map,将上面strArr拆分成 {"a","a","a","b",.....}
        Stream<Stream<Character>> rStream = Arrays.stream(strArr).map(StreamTest::filterCharacter);
        rStream.forEach((st) -> st.forEach(System.out::println));
        System.out.println("--------------------------");
        //使用 flatMap
        Arrays.stream(strArr).flatMap(StreamTest::filterCharacter).forEach(System.out::println);
    }

    public static Stream<Character> filterCharacter(String str) {
        List<Character> list = new ArrayList<>();
        for (char c : str.toCharArray()) {
            list.add(c);
        }
        return list.stream();
    }
  1. 排序
    sorted() : 自然排序 (comparable)
    sorted(Comparator com)
    public static void sort() {
        // sorted()
        String[] strArr = {"ccc", "ddd", "aaa", "bbb"};
        Arrays.stream(strArr).sorted().forEach(System.out::println);
        System.out.println("-----------------------------------");

        // sorted(Comparator com)
        employees.stream().sorted((x, y) -> {
            if (x.getAge().equals(y.getAge())) {
                return x.getName().compareTo(y.getName());
            } else {
                return x.getAge().compareTo(y.getAge());
            }
        }).forEach(System.out::println);
    }

三、终止条件

  1. 查找与匹配
    allMatch : 检查是否匹配所有元素
    anyMatch: 检查是否匹配一个元素
    noneMatch: 检查是否没有匹配任何一个个元素
    findFirst: 返回第一个元素
    findAny: 返回任意一个元素
    count: 计算总数
    max: 返回最大值
    min: 返回最小值
    public static void find() {
        // allMatch
        boolean b = employees.stream().allMatch(x -> x.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b);

        System.out.println("--------------------------------");
        // findFirst
        Optional<Employee> first = employees.stream().findFirst();
        System.out.println(first.get());

        System.out.println("--------------------------------");
        // count
        long count = employees.stream().count();
        System.out.println(count);

        System.out.println("--------------------------------");
        // max min
        Optional<Employee> max = employees.stream().max((x, y) -> Double.compare(x.getAge(), y.getAge()));
        System.out.println(max);
        Optional<Integer> max1 = employees.stream().map(Employee::getAge).max(Double::compare);
        System.out.println(max1.get());
    }
  1. 规约与收集
    规约:可以将流中的元素反复结合起来,得到一个值
public static void test1() {
        // 规约
        Integer[] intArr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        Integer reduce = Arrays.stream(intArr).reduce(0, (x, y) -> x + y);
        System.out.println(reduce);
        System.out.println("--------------------------------------");
        Optional<Double> reduce1 = employees.stream().map(Employee::getSalary).reduce(Double::sum);
        System.out.println(reduce1.get());
        System.out.println("##############################");


        // 收集
        List<Employee> collect = employees.stream().collect(Collectors.toList());
        Set<Employee> collect1 = employees.stream().collect(Collectors.toSet());
        HashSet<String> collect2 = employees.stream().map(Employee::getName).collect(Collectors.toCollection(HashSet::new));
        // 总数 : Collectors.counting()
        // 平均值: Collectors.averagingDouble();
        // 总和: Collectors.summingDouble();


        // 其他获取总数,平均值的方法
        DoubleSummaryStatistics collect7 = employees.stream().collect(Collectors.summarizingDouble(Employee::getAge));
        double average = collect7.getAverage();
        long count = collect7.getCount();
        double max = collect7.getMax();
        double min = collect7.getMin();
        double sum = collect7.getSum();



        // 最值
        Optional<Employee> collect3 = employees.stream().collect(Collectors.maxBy((x, y) -> Double.compare(x.getSalary(), y.getSalary())));
        // 分组
        Map<Employee.Status, List<Employee>> collect4 = employees.stream().collect(Collectors.groupingBy(Employee::getStatus));
        // 多级分组
        Map<Employee.Status, Map<Integer, List<Employee>>> collect5 = employees.stream().collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy(Employee::getAge)));
        // 分区,满足条件的一个区,不满足条件的一个区
        Map<Boolean, List<Employee>> collect6 = employees.stream().collect(Collectors.partitioningBy(e -> e.getAge() > 35));


        // join
        String collect8 = employees.stream().map(Employee::getName).collect(Collectors.joining());  // 将每个employee中的name相连
        String collect9 = employees.stream().map(Employee::getName).collect(Collectors.joining(","));  // 将每个employee中的name相连,用‘,’隔开
        String collect10 = employees.stream().map(Employee::getName).collect(Collectors.joining(",", "++", "++"));// 将每个employee中的name相连,用‘,’隔开,前后加上++
    }

四、并行流

并行流
.parallel() :利用fork/join框架并行执行,并行执行,提高效率。

    public static void test2(){
        Instant start = Instant.now();
        LongStream.rangeClosed(0, 99999999999L)
                .parallel()
                .reduce(0, Long::sum);
        Instant end = Instant.now();
        System.out.println(Duration.between(start,end).toMillis());

        System.out.println("--------------------------");
        employees.stream()
                .parallel()
                .filter((x) -> x.age > 35).forEach(System.out::println);
    }

本次测试一共使用两个类,都粘贴在下面

  1. StreamTest

import java.time.Duration;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.LongStream;
import java.util.stream.Stream;

/**
 * Stream 的三个步骤
 * <p>
 * 1:创建
 * <p>
 * 2:处理
 * <p>
 * 3:终止操作
 */
public class StreamTest {

    static List<Employee> employees = Arrays.asList(
            new Employee("张三", 18, 9999.99, Employee.Status.FREE),
            new Employee("李四", 58, 5555.55, Employee.Status.VOCATION),
            new Employee("王五", 26, 3333.33, Employee.Status.FREE),
            new Employee("赵六", 36, 6666.66, Employee.Status.FREE),
            new Employee("田七", 12, 8888.88, Employee.Status.BUSY),
            new Employee("田七", 12, 8888.88, Employee.Status.FREE),
            new Employee("田七", 12, 8888.88, Employee.Status.FREE)
    );

    public static void main(String[] args) {
        // 创建测试
//        createStream();
        // 筛选与切片测试
//        test();

        // 映射
//        testMap();

        // 排序
//        sort();

        // 查找与匹配
//        find();

        // 规约与收集
//        test1();

        // 并行测试
        test2();
    }



    public static void createStream() {
        // 1:collection系列
        List<String> srrLIst = new ArrayList<>();
        Stream<String> stream = srrLIst.stream();

        // 2.Arrays
        Integer[] ints = new Integer[10];
        Stream<Integer> stream1 = Arrays.stream(ints);

        // 3.Stream.of
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);

        // 4.无限流 Stream.iterate();
        Stream<Integer> iterate = Stream.iterate(0, x -> x + 2);

        // 5.Stream.generate();
        Stream<Double> generate = Stream.generate(Math::random);
    }

    /**
     * 1:筛选与切片
     * filter:过滤得到符合条件的数据
     * limit:拿到结果的前几条
     * skip:跳过结果的前几条
     * distinct:去重,注意,依靠hashcode,equals 方法去重
     */
    public static void test() {
        // filter
        employees.stream().filter((x) -> x.age > 35).forEach(System.out::println);
        System.out.println("----------------------------------");
        // limit
        employees.stream().filter((x) -> x.salary > 5000)
                .limit(2)
                .forEach(System.out::println);

        System.out.println("----------------------------------");
        // skip
        employees.stream().filter((x) -> x.salary > 5000)
                .skip(2)
                .forEach(System.out::println);

        System.out.println("----------------------------------");
        // distinct
        employees.stream().filter((x) -> x.salary > 5000)
                .distinct()
                .forEach(System.out::println);
    }

    /**
     * 映射
     * map: 接受一个函数作为参数,该函数会应用到没一个元素上,并将其映射成一个新的元素
     * flatMap: 将流中的每个值都转化为另一个流,并且将所有流连接成一个流。
     */
    public static void testMap() {
        // map
        String[] strArr = {"aaa", "bbb", "ccc", "ddd"};
        Arrays.stream(strArr).map(String::toUpperCase).forEach(System.out::println);
        System.out.println("--------------------------");
        employees.stream().map(Employee::getName).forEach(System.out::println);
        System.out.println("#########################");
        // flatMap
        // 如果只使用map,将上面strArr拆分成 {"a","a","a","b",.....}
        Stream<Stream<Character>> rStream = Arrays.stream(strArr).map(StreamTest::filterCharacter);
        rStream.forEach((st) -> st.forEach(System.out::println));
        System.out.println("--------------------------");
        //使用 flatMap
        Arrays.stream(strArr).flatMap(StreamTest::filterCharacter).forEach(System.out::println);
    }

    public static Stream<Character> filterCharacter(String str) {
        List<Character> list = new ArrayList<>();
        for (char c : str.toCharArray()) {
            list.add(c);
        }
        return list.stream();
    }

    /**
     * 排序
     * <p>
     * sorted() : 自然排序 (comparable)
     * sorted(Comparator com)
     */
    public static void sort() {
        // sorted()
        String[] strArr = {"ccc", "ddd", "aaa", "bbb"};
        Arrays.stream(strArr).sorted().forEach(System.out::println);
        System.out.println("-----------------------------------");

        // sorted(Comparator com)
        employees.stream().sorted((x, y) -> {
            if (x.getAge().equals(y.getAge())) {
                return x.getName().compareTo(y.getName());
            } else {
                return x.getAge().compareTo(y.getAge());
            }
        }).forEach(System.out::println);
    }


    /**
     * 查找与匹配
     * <p>
     * allMatch : 检查是否匹配所有元素
     * anyMatch: 检查是否匹配一个元素
     * noneMatch: 检查是否没有匹配任何一个个元素
     * findFirst: 返回第一个元素
     * findAny: 返回任意一个元素
     * count: 计算总数
     * max: 返回最大值
     * min: 返回最小值
     */
    public static void find() {
        // allMatch
        boolean b = employees.stream().allMatch(x -> x.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b);

        System.out.println("--------------------------------");
        // findFirst
        Optional<Employee> first = employees.stream().findFirst();
        System.out.println(first.get());

        System.out.println("--------------------------------");
        // count
        long count = employees.stream().count();
        System.out.println(count);

        System.out.println("--------------------------------");
        // max min
        Optional<Employee> max = employees.stream().max((x, y) -> Double.compare(x.getAge(), y.getAge()));
        System.out.println(max);
        Optional<Integer> max1 = employees.stream().map(Employee::getAge).max(Double::compare);
        System.out.println(max1.get());
    }

    /**
     * 规约
     * 可以将流中的元素反复结合起来,得到一个值
     */
    public static void test1() {
        // 规约
        Integer[] intArr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        Integer reduce = Arrays.stream(intArr).reduce(0, (x, y) -> x + y);
        System.out.println(reduce);
        System.out.println("--------------------------------------");
        Optional<Double> reduce1 = employees.stream().map(Employee::getSalary).reduce(Double::sum);
        System.out.println(reduce1.get());
        System.out.println("##############################");


        // 收集
        List<Employee> collect = employees.stream().collect(Collectors.toList());
        Set<Employee> collect1 = employees.stream().collect(Collectors.toSet());
        HashSet<String> collect2 = employees.stream().map(Employee::getName).collect(Collectors.toCollection(HashSet::new));
        // 总数 : Collectors.counting()
        // 平均值: Collectors.averagingDouble();
        // 总和: Collectors.summingDouble();


        // 其他获取总数,平均值的方法
        DoubleSummaryStatistics collect7 = employees.stream().collect(Collectors.summarizingDouble(Employee::getAge));
        double average = collect7.getAverage();
        long count = collect7.getCount();
        double max = collect7.getMax();
        double min = collect7.getMin();
        double sum = collect7.getSum();



        // 最值
        Optional<Employee> collect3 = employees.stream().collect(Collectors.maxBy((x, y) -> Double.compare(x.getSalary(), y.getSalary())));
        // 分组
        Map<Employee.Status, List<Employee>> collect4 = employees.stream().collect(Collectors.groupingBy(Employee::getStatus));
        // 多级分组
        Map<Employee.Status, Map<Integer, List<Employee>>> collect5 = employees.stream().collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy(Employee::getAge)));
        // 分区,满足条件的一个区,不满足条件的一个区
        Map<Boolean, List<Employee>> collect6 = employees.stream().collect(Collectors.partitioningBy(e -> e.getAge() > 35));


        // join
        String collect8 = employees.stream().map(Employee::getName).collect(Collectors.joining());  // 将每个employee中的name相连
        String collect9 = employees.stream().map(Employee::getName).collect(Collectors.joining(","));  // 将每个employee中的name相连,用‘,’隔开
        String collect10 = employees.stream().map(Employee::getName).collect(Collectors.joining(",", "++", "++"));// 将每个employee中的name相连,用‘,’隔开,前后加上++
    }

    /**
     * 并行流
     *
     * .parallel() :利用fork/join框架并行执行
     */
    public static void test2(){
        Instant start = Instant.now();
        LongStream.rangeClosed(0, 99999999999L)
                .parallel()
                .reduce(0, Long::sum);
        Instant end = Instant.now();
        System.out.println(Duration.between(start,end).toMillis());

        System.out.println("--------------------------");
        employees.stream()
                .parallel()
                .filter((x) -> x.age > 35).forEach(System.out::println);
    }
}
  1. Employee
public class Employee {

    String name;

    Integer age;

    Double salary;

    Status status;

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

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Employee employee = (Employee) o;

        if (name != null ? !name.equals(employee.name) : employee.name != null) return false;
        if (age != null ? !age.equals(employee.age) : employee.age != null) return false;
        if (salary != null ? !salary.equals(employee.salary) : employee.salary != null) return false;
        return status == employee.status;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + (age != null ? age.hashCode() : 0);
        result = 31 * result + (salary != null ? salary.hashCode() : 0);
        result = 31 * result + (status != null ? status.hashCode() : 0);
        return result;
    }

    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 Double getSalary() {
        return salary;
    }

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

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

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

    public enum Status{
        FREE,
        BUSY,
        VOCATION;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值