[java basics] stream API

Stream is an enhancement to the collection object function, focusing on various very convenient and efficient aggregation operations (aggregate operations) or bulk data operations (bulk data operations) on collection objects.

With the help of the same emerging Lambda expression, Stream API greatly improves programming efficiency and program readability, and provides two modes of serial and parallel for aggregation operations. The concurrent mode can take full advantage of multi-core processors and use fork /join Parallelism to split tasks and speed up processing.

The set of elements to be processed is regarded as a stream, the stream is transmitted in the pipeline, and can be processed on the nodes of the pipeline, such as filtering, sorting, aggregation, etc. through these intermediate operations (intermediate operations), and finally by the final operation ( terminal operation) to obtain the result of the previous processing.

Code example:
first refer to an object as the basis of the operation:

List<Employee> employees = Arrays.asList(
            new Employee("张三", 18, 222.22, Employee.Status.FREE),
            new Employee("李四", 18, 111.22, Employee.Status.BUSY),
            new Employee("王五", 18, 221.22, Employee.Status.VOCATION),
            new Employee("赵六", 18 , 333.22, Employee.Status.FREE)
    );

Intermediate operation:

 //region 中间操作——流水线——中间操作不会执行处理

    /**
     * 筛选与切片
     * filter 接受lambda 从流中排除某些元素
     * limit  截断流,使其元素不超过给定数量
     * skip(n) 跳过元素,返回一个扔掉了前n个元素的流,若流中不足n个,返回一个空流
     * distinct 筛选,通过流所生成元素的hashCode()和equals()去除::元素类需要重写hashCode和equals方法
     */
    @Test
    public void test2() {
        //中间操作
        employees.stream()
                .filter((e) -> {
                    System.out.println("跑路");//&& || 找到了就不再执行
                    return e.getAge() > 35;
                })
                .limit(2)
                .skip(1)
                .distinct()
                .forEach(System.out::println);//终止操作

        //终止操作  惰性求值:一次性处理
        // stream.forEach(System.out::println);
    }

    //外部迭代,s
    @Test
    public void test3() {
        Iterator<Employee> it = employees.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }
    //endregion

map map, used to map each element to the corresponding result

Example one;

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
// 获取对应的平方数
List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());

Example 2; Extract the merged string

/**
     * map 接受lambda,将元素转换成其他形式或提取信息
     * map接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
     * flatMap 接收一个函数作为参数,将流中每个值都换成另个流,然后把所有流连接成一个流
     */
    @Test
    public void test5() {
        List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd");

        list.stream()//获取流
                .map((str) -> str.toUpperCase())//函数
                .forEach(System.out::println);
        Stream<Stream<Character>> streamStream = list.stream()
                .map(TESTStreamAPI::filterCharacter);//{{a,a,a},{b,b,b}……}
        streamStream.forEach((sm) -> {
            sm.forEach(System.out::println);

            //flatMap 接收一函数作参数,将流中每个值都换成另个流并合成一个流
            Stream<Character> sm2 = list.stream()
                    .flatMap(TESTStreamAPI::filterCharacter);//{a,a,a,b,b,b……}
            sm2.forEach(System.out::println);
        });
    }

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

Find and match:

 @Test
    public void test11(){
        boolean boolean1 = employees.stream()
                .allMatch((e)->e.getStatus().equals(Employee.Status.BUSY));//allMatch——检查是否匹配所有元素

        boolean bool2 = employees.stream()
                .anyMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));//anyMatc——检查是否只是匹配一个元素

        boolean b3 = employees.stream()
                .noneMatch((e) ->e.getStatus().equals(Employee.Status.BUSY));//noneMatch——是否没有匹配所有元素

        Optional<Employee> employeeOptional = employees.stream()
                .sorted((e1,e2)-> -Double.compare(e1.getSalary(),e2.getSalary()))
                .findFirst();//findFirst——返回符合条件的第一个元素,sort排序选取的最低的,"-" 获取最高的

        Optional<Employee> employeeOptional2 = employees.parallelStream()//parallelsteam获取并行(多个线程同时找,谁先找到用谁),stream串行(一个一个找)
                .filter((e)-> e.getStatus().equals(Employee.Status.FREE))
                .findAny();//findany返回当前流中任意元素

        Long count = employees.stream()
                .count();//返回流中元素总个数 终止操作

        Optional<Employee> maxOptionalEmployee = employees.stream()
                .max((e1,e2)-> Double.compare(e1.getSalary(),e2.getSalary()));//终止操作 max流中元素最大值

        Optional<Double> minOptionalEmployee = employees.stream()
                .map(Employee::getSalary)
                .min(Double::compare);//终止操作最小值

    }

Reduction: Merge

   @Test
    public void test1() {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        Integer sum = list.stream()
                .reduce(0, (x, y) -> x + y);//从0开始结合上面的list累加

        Optional<Double> op = employees.stream()
                .map(Employee::getSalary)//得到工资
                .reduce(Double::sum);//工资getSalary总和sum
    }

Collection: Merge, Group

  //region 收集collect(Collector c) 将流转换为其他形式,接收一个Collector接口的实现

    /**
     * Collector接口中方法实现决定了怎么对流执行收集操作(收集到是List、set还是map)
     * 其实现类提供了很多静态方法,方便地创建常见收集器实例
     */
    @Test
    public void test2() {

        //region Collector接口中方法实现决定了如何对流执行收集操作(收集到List、set、map)
        List<String> list = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toList());//接口中方法实现 将流收集到list中
        list.forEach(System.out::println);

        Set<String> set = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toSet());//接口中方法实现 将流收集到set中
        set.forEach(System.out::println);

        HashSet<String> hashSet = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toCollection(HashSet::new));//接口中方法实现 将流收集到map中
        hashSet.forEach(System.out::println);
        //endregion

        //region 其实现类提供了很多静态方法,方便地创建常见收集器实例
        Long count = employees.stream()
                .collect(Collectors.counting());//总数
        Double avg = employees.stream()
                .collect(Collectors.averagingDouble(Employee::getSalary));//平均值
        Double sum = employees.stream()
                .collect(Collectors.summingDouble(Employee::getSalary));//总和
        Optional<Employee> max = employees.stream()
                .collect(Collectors.maxBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));//最大值
        Optional<Double> min = employees.stream()
                .map(Employee::getSalary)
                .collect(Collectors.minBy(Double::compare));//最小值
        //endregion

        //region 分组
        Map<Employee.Status, List<Employee>> map = employees.stream()
                .collect(Collectors.groupingBy(Employee::getStatus));

        Map<Employee.Status, Map<String, List<Employee>>> mapMap = employees.stream()//先根据状态再根据年级
                .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {
                    if (((Employee) e).getAge() <= 35) {
                        return "青年";
                    } else if (((Employee) e).getAge() <= 50) {
                        return "中年";
                    } else {
                        return "老年";
                    }
                })));
        Map<Boolean,List<Employee>> booleanListMap = employees.stream()
                .collect(Collectors.partitioningBy((e)->e.getSalary()>8000));//分区,符合的一个区不符合的一个区false=[] true=[]

        DoubleSummaryStatistics doubleSummaryStatistics = employees.stream()
                .collect(Collectors.summarizingDouble(Employee::getSalary));
        doubleSummaryStatistics.getAverage();//平均值、最大、最小

        String str = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.joining(","));//分隔符,(“,”,“---”,“------”)后三个是开头和结尾
        //endregion

    }

    //endregion

Summary: rookie
tutorial

The streams api in java8 explains the
   stream slave operation type in detail:

  • Intermediate (transformation operation): Followed by 0 or more intermediate operations, open the stream, data mapping or filtering, return to the stream, hand over the next operation, lazy (only merged during the Terminal operation, completed in one cycle)
  • Terminal: One at a time, the last operation, which actually starts the traversal of the stream, generates a result or side effect
  • Total: There is a collection of operation functions in Stream. Each conversion operation is to put the conversion function into this collection, loop the corresponding collection of Stream during Terminal operation, and then execute all functions for each element.
  • short-circuting: a necessary but not sufficient condition (when operating on an infinite stream, and you want to complete the operation in a limited time)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325548808&siteId=291194637