java8之Stream API

(一)Stream API简述

Java8中有两大最为重要的改变。第一个是 Lambda 表达式,另外一个则是 Stream API(java.util.stream.*)Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对 集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。 使Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数 据库查询。也可以使用 Stream API 来并行执行操作。简而言之, Stream API 提供了一种高效且易于使用的处理数据的方式。

1.流(Stream) 到底是什么呢?

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

注意:

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

2.操作流的三个步骤:

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

(二)Stream API的使用

1.创建Stream的6种方法

//方法一:集合创建流的方法
        List<Integer> list = Arrays.asList(1,2,3,4,5);
        Stream<Integer> stream = list.stream();
        Stream<Integer> parallelStream = list.parallelStream();

        //方法二:集合创建流
        int[] a = {1,2,3,4,5};
        IntStream intStream = Arrays.stream(a);

        //方法三:任意数值创建流
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);

        //方法四:由函数创建无限流
        Stream<Integer> limit = Stream.iterate(0, n -> n+2).limit(3);
        limit.forEach(s-> System.out.println("s = " + s));
        Stream<Double> generateA = Stream.generate(new Supplier<Double>() {
            @Override
            public Double get() {
                return java.lang.Math.random();
            }
        });

        Stream<Double> generateB = Stream.generate(()-> java.lang.Math.random());
        Stream<Double> generateC = Stream.generate(Math::random);

2.Stream中间操作

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

2.1 映射

映射
方法描述
map(Function<? super P_OUT, ? extends R> mapper)

接收一个函数作为参数,该函数会被应用到每个元

素上,并将其映射成一个新的元素。

mapToDouble(ToDoubleFunction<? super P_OUT> mapper)

接收一个函数作为参数,该函数会被应用到每个元

素上,产生一个新的 DoubleStream。

mapToInt(ToIntFunction<? super P_OUT> mapper)

接收一个函数作为参数,该函数会被应用到每个元

素上,产生一个新的 IntStream。

mapToLong(ToLongFunction<? super P_OUT> mapper)

接收一个函数作为参数,该函数会被应用到每个元

素上,产生一个新的 LongStream。

flatMap(Function<? super P_OUT, ? extends Stream<? extends R>> mapper)

接收一个函数作为参数,将流中的每个值都换成另

一个流,然后把所有流连接成一个流。

方法使用

 List<Employee> emps = Arrays.asList(
                new Employee(102, "李四", 59, 6666.66, Employee.Status.BUSY),
                new Employee(101, "张三", 18, 9999.99, Employee.Status.FREE),
                new Employee(103, "王五", 28, 3333.33, Employee.Status.VOCATION),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.BUSY),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.FREE),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.FREE),
                new Employee(105, "田七", 38, 5555.55, Employee.Status.BUSY)
        );
        //提取某个字段
        Stream<String> stringStream = emps.stream().map(employee -> employee.getName());
        DoubleStream doubleStream = emps.stream().mapToDouble(employee -> employee.getSalary());
        IntStream intStream = emps.stream().mapToInt(employee -> employee.getAge());

        //多个流合并成一个流,结果:list = [1, 2, 3, 4, 5, 6]
        List<Integer> list = Stream.of(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6))
                .flatMap(numbers -> numbers.stream()).collect(Collectors.toList());
        System.out.println("list = " + list);

2.2排序

排序
方法描述
sorted()

产生一个新流,其中按自然顺序排序

sorted(Comparator<? super T> comparator)

产生一个新流,其中按比较器顺序排序

方法使用

 List<Employee> emps = Arrays.asList(
                new Employee(102, "李四", 59, 6666.66, Employee.Status.BUSY),
                new Employee(101, "张三", 18, 9999.99, Employee.Status.FREE),
                new Employee(103, "王五", 28, 3333.33, Employee.Status.VOCATION),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.BUSY),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.FREE),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.FREE),
                new Employee(105, "田七", 38, 5555.55, Employee.Status.BUSY)
        );
        //从小到大排序
        emps.stream().map(Employee::getAge).sorted().forEach(System.out::println);
        //年龄相等按姓名排序,否则按年排序(升序)
        emps.stream()
                .sorted((x, y) -> {
                    if (x.getAge() == y.getAge()) {
                        return x.getName().compareTo(y.getName());
                    } else {
                        return Integer.compare(x.getAge(), y.getAge());
                    }
                }).forEach(System.out::println);

2.3归纳求和

规约
方法说明
reduce(BinaryOperator<T> b)

可以将流中元素反复结合起来,得到一个值。返回 Optional<T>

reduce(T identity, BinaryOperator<T> b)

可以将流中元素反复结合起来,得到一个值。返回 T

方法使用

List<Employee> emps = Arrays.asList(
                new Employee(102, "李四", 59, 6666.66, Employee.Status.BUSY),
                new Employee(101, "张三", 18, 9999.99, Employee.Status.FREE),
                new Employee(103, "王五", 28, 3333.33, Employee.Status.VOCATION),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.BUSY),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.FREE),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.FREE),
                new Employee(105, "田七", 38, 5555.55, Employee.Status.BUSY)
        );
        //累加求和总薪水=48888.84000000001
        Optional<Double> sumSalary = emps.stream()
                .map(Employee::getSalary)
                .reduce(Double::sum);
        System.out.println("总薪水=" + sumSalary);

        //累加求和总年龄=167
        Optional<Integer> sumAge = emps.stream()
                .map(Employee::getAge)
                .reduce(Integer::sum);
        System.out.println("总年龄=" + sumAge);

        //累加employee.getAge()+1,累加求和总年龄=174
        double sum = emps.stream().mapToDouble(employee->employee.getAge()+1).sum();
        System.out.println("sum = " + sum);

        //归纳求和=15
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
        Integer sums = list.stream().reduce(0, (x, y) -> x + y);
        System.out.println("归纳求和=" + sums);

        //optional = 167
        Optional<Integer> optional = emps.stream().map(Employee::getAge).collect(Collectors.reducing(Integer::sum));
        System.out.println("optional = " + optional.get());

2.4筛选与切片

筛选与切片
方法说明
filter(Predicate<? super T> predicate)

接收 Lambda , 从流中排除某些元素。

distinct()

筛选,通过流所生成元素的 hashCode() 和 equals() 去

除重复元素

limit(long maxSize)

截断流,使其元素不超过给定数量

skip(long n)

跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素

不足 n 个,则返回一个空流。与 limit(n) 互补

方法使用

        //distinct--去除集合重复元素
        List<String> list = Arrays.asList("AA", "BB", "CC", "BB", "CC", "AA", "AA");
        long  counts = list.stream().distinct().count();

        //filter--接收 Lambda ,从流中排除AA些元素。
        Stream<String> stream = list.stream().filter(str -> !str.equals("AA"));
        stream.forEach(str-> System.out.println("str = " + str));

        //获取前2个元素,AA,BB
        Stream<String> limit = list.stream().limit(2);
        limit.forEach(s -> System.out.println("s = " + s));

        //skip
        Stream<String> skip = list.stream().skip(2);
        skip.forEach(skips-> System.out.println("skips = " + skips));

2.5查找与匹配

查找与匹配
方法说明
allMatch(Predicate<? super T> predicate)

检查是否匹配所有元素

anyMatch(Predicate<? super T> predicate)

检查是否至少匹配一个元素

noneMatch(Predicate<? super T> predicate)

检查是否没有匹配所有元素

findFirst()

返回第一个元素

findAny()

返回当前流中的任意元素

count()

返回流中元素总数

max(Comparator<? super T> comparator)

返回流中最大值

min(Comparator<? super T> comparator)
返回流中最小值
forEach(Consumer<? super T> action)
内部迭代(使用 Collection 接口需要用户去做迭
代,称为外部迭代。相反,Stream API 使用内部迭代——它帮你把迭代做了)

方法使用

        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
        //allMatch--检查是否匹配所有元素
        boolean allMatch = list.stream().allMatch(value -> value.equals(3));
        //anyMatch--检查是否至少匹配一个元素
        boolean anyMatch = list.stream().anyMatch(vaule -> vaule.equals(3));
        //noneMatch--检查是否没有匹配的元素
        boolean noneMatch = list.stream().noneMatch(vaule -> vaule.equals(3));
        //findFirst--返回第一个元素
        Integer firstnumber = list.stream().findFirst().get();
        //findAny--返回当前流中的任意元素
        Integer anyNumber = list.stream().findAny().get();
        //count——返回流中元素的总个数
        long count = list.stream().count();
        //max——返回流中最大值
        Integer max = list.stream().max(Integer::compare).get();
        //min——返回流中最小值
        Integer min = list.stream().min(Integer::compare).get();

3.Stream的终止操作

流中元素收集
方法说明
collect(Collector<? super T, A, R> collector)

将流转换为其他形式。接收一个 Collector接口的

实现,用于给Stream中元素做汇总的方法

toList()

把流中元素收集到List

toSet()

把流中元素收集到Set

toCollection()

把流中元素收集到创建的集合

counting()

计算流中元素的个数

summingInt(ToIntFunction<? super T> mapper)

对流中元素的整数属性求和

averagingInt(ToIntFunction<? super T> mapper)

计算流中元素Integer属性的平均

summarizingInt(ToIntFunction<? super T> mapper) 

收集流中Integer属性的统计值。如:平均值

joining()

连接流中每个字符串

maxBy(Comparator<? super T> comparator)
根据比较器选择最大值
reducing(BinaryOperator<T> op)

从一个作为累加器的初始值

开始,利用BinaryOperator

流中元素逐个结合,从而归

约成单个值

 collectingAndThen(Collector<T,A,R> downstream,
                                                            Function<R,RR> finisher)

包裹另一个收集器,对其结

果转换函数

inthow= list.stream().collect(Collectors.collectingAndThen(Collectors.toList()

groupingBy(Function<? super T, ? extends K> classifier)

根据某属性值对流分组,属

性为K,结果为V

 partitioningBy(Predicate<? super T> predicate)

根据truefalse进行分区

3.1Java8操作集合,实现List,Set,Map遍历

        List<Employee> emps = Arrays.asList(
                new Employee(102, "李四", 59, 6666.66, Employee.Status.BUSY),
                new Employee(101, "张三", 18, 9999.99, Employee.Status.FREE),
                new Employee(103, "王五", 28, 3333.33, Employee.Status.VOCATION),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.BUSY),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.FREE),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.FREE),
                new Employee(105, "田七", 38, 5555.55, Employee.Status.BUSY)
        );
        //抽取一个元素封装到另一个List容器
        List<String> list = emps.stream().map(Employee::getName).collect(Collectors.toList());
        //遍历list
        list.forEach(s->{
            System.out.println("s = " + s);
        });

        //抽取一个元素封装到Set容器
        Set<Double> set = emps.stream().map(Employee::getSalary).collect(Collectors.toSet());
        //遍历set
        set.forEach(d -> {
            System.out.println("d = " + d);
        });
        System.out.println("set = " + set);

        /**
         * List -> Map
         * 需要注意的是:
         * toMap 如果集合对象有重复的key,会报错Duplicate key ....
         *  Employee1,Employee2的id都为1。
         *  可以用 (k1,k2)->k1 来设置,如果有重复的key,则保留key1,舍弃key2
         */
        Map<Integer, Employee> map = emps.stream().collect(Collectors.toMap(Employee::getId, Employee -> Employee, (k1, k2) -> k1));
        System.out.println("map = " + map);
        //遍历map
        map.forEach((s,v)->{
            System.out.println("s = " + s);
        });

3.2一级分组、二级分组

               List<Employee> emps = Arrays.asList(
                new Employee(102, "李四", 59, 6666.66, Employee.Status.BUSY),
                new Employee(101, "张三", 18, 9999.99, Employee.Status.FREE),
                new Employee(103, "王五", 28, 3333.33, Employee.Status.VOCATION),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.BUSY),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.FREE),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.FREE),
                new Employee(105, "田七", 38, 5555.55, Employee.Status.BUSY)
        );
        Map<Employee.Status, List<Employee>> map = emps.stream().collect(Collectors.groupingBy(Employee::getStatus));
        System.out.println("map = " + map);

        Map<Employee.Status, Map<String, List<Employee>>> mapMap = emps.stream().collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy(
                (employee) -> {
                    if (employee.getAge() >= 60)
                        return "老年";
                    else if (employee.getAge() >= 35)
                        return "中年";
                    else
                        return "成年";
                }
        )));
        System.out.println("mapMap = " + mapMap);

3.3方法的使用

        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
        //toList--元素收集到List容器
        List<Integer> tolist = list.stream().collect(Collectors.toList());
        //toSet--元素收集到Set容器
        Set<Integer> set = list.stream().collect(Collectors.toSet());
        //toCollection--把流中元素收集到创建的集合
        ArrayList<Integer> arrayList = list.stream().collect(Collectors.toCollection(ArrayList::new));
        //counting--计算集合中元素的个数
        Long aLong = list.stream().collect(Collectors.counting());
        //summingInt--求集合中元素和
        Integer sum = list.stream().collect(Collectors.summingInt(i -> i));
        //averagingInt--求平均值
        Double average = list.stream().collect(Collectors.averagingInt(i -> i));
        System.out.println("average = " + average);
        // 结果: intSummary = IntSummaryStatistics{count=5, sum=15, min=1, average=3.000000, max=5}
        IntSummaryStatistics intSummary = list.stream().collect(Collectors.summarizingInt(i -> i));
        //maxBy--根据比较器选择最大值
        Optional<Integer> optional = list.stream().collect(Collectors.maxBy(comparingInt(i -> i)));
        System.out.println("optional = " + optional.get());

3.4案例演示

/**
 * 一、 Stream 的操作步骤
 * <p>
 * 1. 创建 Stream
 * <p>
 * 2. 中间操作
 * <p>
 * 3. 终止操作
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class StreamApiTest {
    List<Employee> emps = Arrays.asList(
            new Employee(102, "李四", 59, 6666.66, Employee.Status.BUSY),
            new Employee(101, "张三", 18, 9999.99, Employee.Status.FREE),
            new Employee(103, "王五", 28, 3333.33, Employee.Status.VOCATION),
            new Employee(104, "赵六", 8, 7777.77, Employee.Status.BUSY),
            new Employee(104, "赵六", 8, 7777.77, Employee.Status.FREE),
            new Employee(104, "赵六", 8, 7777.77, Employee.Status.FREE),
            new Employee(105, "田七", 38, 5555.55, Employee.Status.BUSY)
    );
    @Test
    public void  test(){
        //提取某个字段
        Stream<String> stringStream = emps.stream().map(employee -> employee.getName());
        DoubleStream doubleStream = emps.stream().mapToDouble(employee -> employee.getSalary());
        IntStream intStream = emps.stream().mapToInt(employee -> employee.getAge());

        //多个流合并成一个流,结果:list = [1, 2, 3, 4, 5, 6]
        List<Integer> list = Stream.of(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6))
                .flatMap(numbers -> numbers.stream()).collect(Collectors.toList());
        System.out.println("list = " + list);

    }
    /**
     * 基本使用,从集合中提取对象的一个字段
     */
    @Test
    public void test001() {
        //方式一: 使用lambda
        Stream<String> stringStream = emps.stream().map((employee -> employee.getName()));
        stringStream.forEach(System.out::println);

        //方式二
        emps.stream().map(Employee::getName).forEach(System.out::println);
    }
    /**
     * Java8操作集合,实现List,Set,Map遍历
     */
    @Test
    public void test002() {
        //抽取一个元素封装到另一个List容器
        List<String> list = emps.stream().map(Employee::getName).collect(Collectors.toList());
        //遍历list
        list.forEach(s->{
            System.out.println("s = " + s);
        });

        //抽取一个元素封装到Set容器
        Set<Double> set = emps.stream().map(Employee::getSalary).collect(Collectors.toSet());
        //遍历set
        set.forEach(d -> {
            System.out.println("d = " + d);
        });
        System.out.println("set = " + set);

        /**
         * List -> Map
         * 需要注意的是:
         * toMap 如果集合对象有重复的key,会报错Duplicate key ....
         *  Employee1,Employee2的id都为1。
         *  可以用 (k1,k2)->k1 来设置,如果有重复的key,则保留key1,舍弃key2
         */
        Map<Integer, Employee> map = emps.stream().collect(Collectors.toMap(Employee::getId, Employee -> Employee, (k1, k2) -> k1));
        System.out.println("map = " + map);
        //遍历map
        map.forEach((s,v)->{
            System.out.println("s = " + s);
        });
    }

    /**
     * 对集合进行过滤操作
     */
    @Test
    public void test003() {
        //这个过滤只获取大于5000&&Employee.Status.BUSY,而不是过滤掉
        List<Employee> list = emps.stream()
                .filter(employee -> employee.getSalary() > 5000
                        && employee.getStatus().equals(Employee.Status.BUSY))
                .collect(Collectors.toList());
        for(Employee employee : list){
            System.out.println("employee = " + employee);
        }
    }
    /**
     * 分组:
     * 一级分组
     * 多级分组
     */
    @Test
    public void test004() {
        Map<Employee.Status, List<Employee>> map = emps.stream().collect(Collectors.groupingBy(Employee::getStatus));
        System.out.println("map = " + map);

        Map<Employee.Status, Map<String, List<Employee>>> mapMap = emps.stream().collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy(
                (employee) -> {
                    if (employee.getAge() >= 60)
                        return "老年";
                    else if (employee.getAge() >= 35)
                        return "中年";
                    else
                        return "成年";
                }
        )));
        System.out.println("mapMap = " + mapMap);

    }
    /**
     * 归纳求和
     */
    @Test
    public void test005() {
        //累加求和总薪水=48888.84000000001
        Optional<Double> sumSalary = emps.stream()
                .map(Employee::getSalary)
                .reduce(Double::sum);
        System.out.println("总薪水=" + sumSalary);

        //累加求和总年龄=167
        Optional<Integer> sumAge = emps.stream()
                .map(Employee::getAge)
                .reduce(Integer::sum);
        System.out.println("总年龄=" + sumAge);

        //累加employee.getAge()+1,累加求和总年龄=174
        double sum = emps.stream().mapToDouble(employee->employee.getAge()+1).sum();
        System.out.println("sum = " + sum);

        //归纳求和=15
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
        Integer sums = list.stream().reduce(0, (x, y) -> x + y);
        System.out.println("归纳求和=" + sums);

        //optional = 167
        Optional<Integer> optional = emps.stream().map(Employee::getAge).collect(Collectors.reducing(Integer::sum));
        System.out.println("optional = " + optional.get());
    }


    /*
    allMatch——检查是否匹配所有元素
    anyMatch——检查是否至少匹配一个元素
    noneMatch——检查是否没有匹配的元素
    findFirst——返回第一个元素
    findAny——返回当前流中的任意元素
    count——返回流中元素的总个数
    max——返回流中最大值
    min——返回流中最小值
    */
    @Test
    public void test006() {

        //allMatch——检查是否匹配所有元素
        boolean b1 = emps.stream().allMatch((employee -> employee.getStatus().equals(Employee.Status.BUSY)));
        System.out.println("返回状态:" + b1);

        //anyMatch——检查是否至少匹配一个元素
        boolean b2 = emps.stream().anyMatch((employee -> employee.getStatus().equals(Employee.Status.BUSY)));
        System.out.println("返回状态:" + b2);

        //检查是否没有匹配的元素
        boolean b3 = emps.stream().noneMatch((employee -> employee.getStatus().equals(Employee.Status.BUSY)));
        System.out.println("返回状态:" + b3);

        //返回第一个元素
        Optional<Employee> optional = emps.stream()
                .sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))
                .findFirst();
        System.out.println("获取第一个元素" + optional.get());

        //返回当前流中的任意元素
        Optional<Employee> any = emps.parallelStream().filter((employee -> employee.getStatus().equals(Employee.Status.FREE)))
                .findAny();
        System.out.println("返回当前流中的任意元素" + any.get());

        //返回流中元素的总个数
        long count = emps.stream().count();
        System.out.println("返回流中元素的总个数==" + count);

        //返回流中最大值
        Optional<Double> max = emps.stream().map(Employee::getSalary).max(Double::compare);
        System.out.println("返回流中最大值==" + max);

        //返回流中最小值
        Optional<Double> min = emps.stream().map(Employee::getSalary).min(Double::compare);
        System.out.println("返回流中最小值==" + min);

    }
    @Test
    public void test007() {
        //取最大薪水
        Optional<Double> maxSalary = emps.stream().map(Employee::getSalary).collect(Collectors.maxBy(Double::compare));
        System.out.println("maxSalary = " + maxSalary.get());

        //取出集合中最大薪水的员工
        Optional<Employee> maxSalaryEmployee = emps.stream().collect(Collectors.maxBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
        System.out.println("maxSalaryEmployee = " + maxSalaryEmployee);

        //取最小薪水
        Optional<Double> minSalary = emps.stream().map(Employee::getSalary).collect(Collectors.minBy(Double::compare));
        System.out.println("minSalary = " + minSalary.get());

        //取出集合中最小薪水的员工
        Optional<Employee> minSalaryEmployee = emps.stream().collect(Collectors.minBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
        System.out.println("minSalaryEmployee = " + minSalaryEmployee.get());

        //计算薪水总和
        Double sumSalary = emps.stream().collect(Collectors.summingDouble(Employee::getSalary));
        System.out.println("sumSalary = " + sumSalary);

        //计算薪水平均值
        Double aveSalary = emps.stream().collect(Collectors.averagingDouble(Employee::getSalary));
        System.out.println("aveSalary = " + aveSalary);

        //计算集合中元素个数
        Long count = emps.stream().collect(Collectors.counting());
        System.out.println("count = " + count);

        //计算薪水最大,最小,平均,总和等等
        DoubleSummaryStatistics summaryStatistics = emps.stream().collect(Collectors.summarizingDouble(Employee::getSalary));
        System.out.println("summaryStatistics = " + summaryStatistics.getMax());
    }
    @Test
    public void test008() {
        List<String> strList = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
        strList.stream().map(String::toUpperCase).forEach(System.out::println);
        System.out.println("--------------自定义方法过滤-----------------");
        strList.stream().map(StreamApiTest::filterCharacter).forEach(System.out::println);

    }

    public static Stream<Character> filterCharacter(String str) {
        List<Character> list = new ArrayList<>();
        for (Character ch : str.toCharArray()) {
            list.add(ch);
        }
        return list.stream();
    }
    //需求:搜索名字中 “六” 出现的次数
    @Test
    public void test009() {
        Optional<Integer> sum = emps.stream()
                .map(Employee::getName)
                .flatMap(StreamApiTest::filterCharacter)
                .map((ch) -> {
                    if (ch.equals('六'))
                        return 1;
                    else
                        return 0;
                }).reduce(Integer::sum);

        System.out.println(sum.get());
    }

    /**
     * 集合中的元素排序
     */
    @Test
    public void test010() {
        //从小到大排序
        emps.stream().map(Employee::getAge).sorted().forEach(System.out::println);
        //年龄相等按姓名排序,否则按年排序(升序)
        emps.stream()
                .sorted((x, y) -> {
                    if (x.getAge() == y.getAge()) {
                        return x.getName().compareTo(y.getName());
                    } else {
                        return Integer.compare(x.getAge(), y.getAge());
                    }
                }).forEach(System.out::println);
    }

    /**
     * 字符串拼接
     */
    @Test
    public void test011() {
        String s = emps.stream().map(Employee::getName).collect(Collectors.joining("", "First", "End"));
        System.out.println("s = " + s);
    }
    /**
     * 分区操作
     */
    @Test
    public void test12() {
        Map<Boolean, List<Employee>> map = emps.stream().collect(Collectors.partitioningBy(e -> e.getSalary() >= 5000));
        System.out.println("map = " + map);
    }
    @Test
    public void test0013(){
        //rate = 0.666667
        BigDecimal rate = new BigDecimal(2).divide(new BigDecimal(3), 6, BigDecimal.ROUND_HALF_UP);
        System.out.println("rate = " + rate);
    }

}
//employeeList.parallelStream()
//        .map((String orderId) -> userHandler.queryInvestDetailByOrderId(orderId))
//        .filter((PrizeInvestDetailBO prizeInvestDetailBO) -> prizeInvestDetailBO != null && prizeInvestDetailBO.getPrizeType() != null && prizeInvestDetailBO.getPrizeType() == PrizeTypeEnum.COUPON.getCode())
//        .filter((PrizeInvestDetailBO prizeInvestDetailBO) -> userCouponInvestFlowDao.queryByPayOrderId(prizeInvestDetailBO.getPayOrderId()) == null)
//        .forEach((PrizeInvestDetailBO prizeInvestDetailBO) -> userInvestHandler.insertInvestDetail(prizeInvestDetailBO));

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值