Java基础知识回顾13-Stream流
  19qMgiCiiRfc 2023年11月18日 20 0

一、概念

Java8引入一个新特性是Stream流,允许以声明性方式处理数据集合,可以把Stream流看作是遍历数据集合的一个高级迭代器。

Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选、过滤、集合等。

流的来源可以是集合、数组等,流不存储数据目的是处理数据,流只能使用一次。

Stream可以由数组或集合创建,对流的操作分为两种:

1.中间操作,每次返回一个新的流,可以有多个。

2.终端操作,每个流只能进行一次终端操作,终端操作结束后流无法再次使用,终端操作会产生一个新的集合或值。

二、Stream的创建

1.通过集合的stream()方法创建流

package day05;



import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

/**
 * @author qx
 * @date 2023/11/3
 * @des
 */
public class LambdaTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        Stream<String> stream = list.stream();
    }
}

2.使用Arrays.stream()方法用数组创建流

package day05;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

/**
 * @author qx
 * @date 2023/11/3
 * @des
 */
public class LambdaTest {
    public static void main(String[] args) {
        Integer[] arr = {1, 2, 3};
        Stream<Integer> stream = Arrays.stream(arr);
    }
}

3.使用Stream.of()方法用数组创建流

package day05;


import java.util.stream.Stream;

/**
 * @author qx
 * @date 2023/11/3
 * @des
 */
public class LambdaTest {
    public static void main(String[] args) {
        Integer[] arr = {1, 2, 3};
        Stream<Integer> stream = Stream.of(arr);
    }
}

3.使用Stream静态方法创建流

package day05;


import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author qx
 * @date 2023/11/3
 * @des
 */
public class LambdaTest {
    public static void main(String[] args) {
        Integer[] arr = {1, 2, 3};
        // Stream.of
        List<Integer> integerList = Stream.of(arr).collect(Collectors.toList());
        System.out.println(integerList);

        // Stream.iterate
        List<Integer> list = Stream.iterate(0, x -> x + 3).limit(2).collect(Collectors.toList());
        System.out.println(list);

        //Stream.generate
        List<Double> doubleList = Stream.generate(Math::random).limit(3).collect(Collectors.toList());
        System.out.println(doubleList);
    }
}

stream和paralleStream的区别是:stream是顺序流,由主线程按顺序对流进行操作,而paralleStream是并行流,内部以多线程并行执行的方式对流进行操作,但前提是流中的数据处理没有顺序要求。例如筛选集合中的奇数等。

三、常用操作

常用中间操作

方法

说明

filter

用于筛选需要的数据

map

用于映射出新数据

sorted

用于数据排序

limit

用于获取限制条数的数据

终端操作

方法

说明

forEach

遍历数据

find/match

匹配数据

reduce

用于规约数据

max/min/count

聚合数据

创建一个测试的实体类:

package day05;

/**
 * @author qx
 * @date 2023/11/3
 * @des 测试类
 */
public class Student {
    private String name;
    private Integer age;
    private Double salary;

    public Student() {
    }

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

    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;
    }

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

1、遍历/匹配(foreach/find/match)

package day05;

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

/**
 * @author qx
 * @date 2023/11/3
 * @des
 */
public class TestSupplier {

    public static void main(String[] args) {
        List<Student> studentList = initStudents();
        //forEach遍历
        studentList.forEach(s -> System.out.println(s.getName()));
        //findFirst获取第一个数据
        Optional<Student> studentOptional = studentList.stream().findFirst();
        System.out.println(studentOptional.get());
        //findAny获取任意一个数据
        Optional<Student> studentOptional1 = studentList.stream().findAny();
        System.out.println(studentOptional1.get());

        //match allMatch匹配所有
        boolean flag = studentList.stream().allMatch(s -> s.getAge() > 20);
        System.out.println(flag);

        // noneMatch没有一个匹配
        boolean nonedMatch = studentList.stream().noneMatch(s -> s.getAge() > 20);
        System.out.println(nonedMatch);

        // anyMatch匹配其中一个
        boolean aniedMatch = studentList.stream().anyMatch(s -> s.getAge() > 20);
        System.out.println(aniedMatch);
    }

    private static List<Student> initStudents() {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 20, 3000.0));
        studentList.add(new Student("李四", 22, 6000.0));
        studentList.add(new Student("王五", 25, 4000.0));
        studentList.add(new Student("赵六", 23, 5000.0));
        return studentList;
    }
}

输出:

张三
李四
王五
赵六
Student{name='张三', age=20, salary=3000.0}
Student{name='张三', age=20, salary=3000.0}
false
false
true

2.按条件匹配filter

package day05;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author qx
 * @date 2023/11/3
 * @des
 */
public class TestSupplier {

    public static void main(String[] args) {
        List<Student> studentList = initStudents();
        // 筛选年龄超过22的数据
        List<Student> students = studentList.stream().filter(s -> s.getAge() > 22).collect(Collectors.toList());
        System.out.println(students);
    }

    private static List<Student> initStudents() {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 20, 3000.0));
        studentList.add(new Student("李四", 22, 6000.0));
        studentList.add(new Student("王五", 25, 4000.0));
        studentList.add(new Student("赵六", 23, 5000.0));
        return studentList;
    }
}

输出:

[Student{name='王五', age=25, salary=4000.0}, Student{name='赵六', age=23, salary=5000.0}]

3.聚合max、min、count

package day05;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author qx
 * @date 2023/11/3
 * @des
 */
public class TestSupplier {

    public static void main(String[] args) {
        List<Student> studentList = initStudents();
        //max 获取年龄最大的对象数据
        Optional<Student> maxOptional = studentList.stream().max(Comparator.comparing(Student::getAge));
        System.out.println(maxOptional.get());

        //min 获取年龄最小的对象数据
        Optional<Student> minOptional = studentList.stream().min(Comparator.comparing(Student::getAge));
        System.out.println(minOptional.get());

        //count 获取列表的数量
        long count = studentList.stream().count();
        System.out.println(count);
    }

    private static List<Student> initStudents() {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 20, 3000.0));
        studentList.add(new Student("李四", 22, 6000.0));
        studentList.add(new Student("王五", 25, 4000.0));
        studentList.add(new Student("赵六", 23, 5000.0));
        return studentList;
    }
}

输出:

Student{name='王五', age=25, salary=4000.0}
Student{name='张三', age=20, salary=3000.0}
4

4.map和flatMap

package day05;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author qx
 * @date 2023/11/6
 * @des
 */
public class MapTest {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu");
        // map 字符串的元素都改为大写
        List<String> stringList = list.stream().map(s -> s.toUpperCase()).collect(Collectors.toList());
        System.out.println(stringList);
        //flatMap 接收一个函数作为参数,将流中的每个值都转换成另一个流,然后把所有流连接成一个流
        String[] arr = {"a,b,c,d", "e,f,g"};
        List<String> strings = Arrays.asList(arr);
        List<String> resultList = strings.stream().flatMap(s -> {
            String[] array = s.split(",");
            return Arrays.stream(array);
        }).collect(Collectors.toList());
        System.out.println(resultList);
    }
}

输出:

[ZHANGSAN, LISI, WANGWU, ZHAOLIU]
[a, b, c, d, e, f, g]

5.规约reduce

归约,也称缩减,顾名思义,是把一个流缩减成一个值,能实现对集合求和、求乘积和求最值操作。

package day05;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author qx
 * @date 2023/11/3
 * @des
 */
public class TestSupplier {

    public static void main(String[] args) {
        List<Student> studentList = initStudents();
        //对年龄求和
        Optional<Integer> reduce = studentList.stream().map(s -> s.getAge()).reduce((x, y) -> x + y);
        System.out.println(reduce.get());

    }

    private static List<Student> initStudents() {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 20, 3000.0));
        studentList.add(new Student("李四", 22, 6000.0));
        studentList.add(new Student("王五", 25, 4000.0));
        studentList.add(new Student("赵六", 23, 5000.0));
        return studentList;
    }
}

输出:

90

6、收集(toList、toSet、toMap)

package day05;

import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author qx
 * @date 2023/11/3
 * @des
 */
public class TestSupplier {

    public static void main(String[] args) {
        List<Student> students = initStudents();
        // toList
        List<Student> studentList = students.stream().filter(s -> s.getAge() > 20).collect(Collectors.toList());
        System.out.println(studentList);
        // toSet
        Set<Student> studentSet = students.stream().filter(s -> s.getAge() > 22).collect(Collectors.toSet());
        System.out.println(studentSet);
        // toMap
        Map<String, Student> studentMap = students.stream().collect(Collectors.toMap(s -> s.getName(), Function.identity()));
        System.out.println(studentMap);

    }

    private static List<Student> initStudents() {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 20, 3000.0));
        studentList.add(new Student("李四", 22, 6000.0));
        studentList.add(new Student("王五", 25, 4000.0));
        studentList.add(new Student("赵六", 23, 5000.0));
        return studentList;
    }
}

输出:

[Student{name='李四', age=22, salary=6000.0}, Student{name='王五', age=25, salary=4000.0}, Student{name='赵六', age=23, salary=5000.0}]
[Student{name='赵六', age=23, salary=5000.0}, Student{name='王五', age=25, salary=4000.0}]
{李四=Student{name='李四', age=22, salary=6000.0}, 张三=Student{name='张三', age=20, salary=3000.0}, 王五=Student{name='王五', age=25, salary=4000.0}, 赵六=Student{name='赵六', age=23, salary=5000.0}}

7.collect

Collectors提供了一系列用于数据统计的静态方法:

计数:count

平均值:averagingInt、averagingLong、averagingDouble

最值:maxBy、minBy

求和:summingInt、summingLong、summingDouble

统计以上所有:summarizingInt、summarizingLong、summarizingDouble

package day05;

import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author qx
 * @date 2023/11/3
 * @des
 */
public class TestSupplier {

    public static void main(String[] args) {
        List<Student> students = initStudents();
        // 平均年龄
        Double ageDouble = students.stream().collect(Collectors.averagingInt(s -> s.getAge()));
        System.out.println(ageDouble);
        // 求和
        Integer ageSum = students.stream().collect(Collectors.summingInt(s -> s.getAge()));
        System.out.println(ageSum);
        // summarizingDouble统计所有数据
        DoubleSummaryStatistics summaryStatistics = students.stream().collect(Collectors.summarizingDouble(s -> s.getSalary()));
        System.out.println(summaryStatistics);
    }

    private static List<Student> initStudents() {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 20, 3000.0));
        studentList.add(new Student("李四", 22, 6000.0));
        studentList.add(new Student("王五", 25, 4000.0));
        studentList.add(new Student("赵六", 23, 5000.0));
        return studentList;
    }
}

输出:

22.5
90
DoubleSummaryStatistics{count=4, sum=18000.000000, min=3000.000000, average=4500.000000, max=6000.000000}

8.接合joining 

joining可以将stream中的元素用特定的连接符(没有的话,则直接连接)连接成一个字符串。

package day05;

import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author qx
 * @date 2023/11/3
 * @des
 */
public class TestSupplier {

    public static void main(String[] args) {
        List<Student> students = initStudents();
        // 用逗号来拼接名字
        String str = students.stream().map(s -> s.getName()).collect(Collectors.joining(","));
        System.out.println(str);
    }

    private static List<Student> initStudents() {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 20, 3000.0));
        studentList.add(new Student("李四", 22, 6000.0));
        studentList.add(new Student("王五", 25, 4000.0));
        studentList.add(new Student("赵六", 23, 5000.0));
        return studentList;
    }
}
张三,李四,王五,赵六

9.排序sorted

package day05;

import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author qx
 * @date 2023/11/3
 * @des
 */
public class TestSupplier {

    public static void main(String[] args) {
        List<Student> students = initStudents();
        // 按照年龄排序
        List<Student> studentList = students.stream().sorted((s1, s2) -> s1.getAge().compareTo(s2.getAge())).collect(Collectors.toList());
        System.out.println(studentList);
    }

    private static List<Student> initStudents() {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 20, 3000.0));
        studentList.add(new Student("李四", 22, 6000.0));
        studentList.add(new Student("王五", 25, 4000.0));
        studentList.add(new Student("赵六", 23, 5000.0));
        return studentList;
    }
}

输出:

[Student{name='张三', age=20, salary=3000.0}, Student{name='李四', age=22, salary=6000.0}, Student{name='赵六', age=23, salary=5000.0}, Student{name='王五', age=25, salary=4000.0}]


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月18日 0

暂无评论

19qMgiCiiRfc