java中Stream流常用操作

流的分类

Stream

stream 是串行的,通俗来讲就是按顺序执行

parallelStream

parallelStream 是并行的,采用分治的原理实现,先将流拆分,处理完之后再合并处理结果,执行具有不要确定性,不推荐在不适用的场景下使用

常用流的创建

  1. Collection的stream()方法
  2. Stream.of()等流的静态方法
  3. Arrays.stream()方法

流的中间操作

相关示例类如下

  • Student
public class Student {
    private String name; // 姓名
    private String gender; // 性别
    private Integer grade; // 成绩

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

    public Student() {
    }

    public Student(String name, String gender, Integer grade) {
        this.name = name;
        this.gender = gender;
        this.grade = grade;
    }

    public String getName() {
        return name;
    }

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

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Integer getGrade() {
        return grade;
    }

    public void setGrade(Integer grade) {
        this.grade = grade;
    }
}

  • People
public class People {
    private String name; // 姓名
    private String gender; // 性别

    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }

    public People() {
    }

    public People(String name, String gender) {
        this.name = name;
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

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

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }
}

  • 添加数据
ArrayList<Student> list = new ArrayList<>();

// 男生
Student student1 = new Student("张三", "男", 60);
Student student2 = new Student("李四", "男", 70);
Student student3 = new Student("王五", "男", 80);
Student student4 = new Student("赵六", "男", 90);
Student student5 = new Student("钱七", "男", 100);
// 女生
Student student6 = new Student("西施", "女", 100);
Student student7 = new Student("貂蝉", "女", 100);
Student student8 = new Student("王昭君", "女", 100);
Student student9 = new Student("李飞燕", "女", 100);
list.add(student1);
list.add(student2);
list.add(student3);
list.add(student4);
list.add(student5);
list.add(student6);
list.add(student7);
list.add(student8);
list.add(student9);

map

map 常用来将一个流映射为另外一个流(需要传入的参数就是映射的规则)

  • 例子1:将所有学生的姓名拿出来组成一个新的集合
 List<String> studentNames = list.stream().map(Student::getName).collect(Collectors.toList());
 System.out.println(studentNames);
// 输出结果
// [张三, 李四, 王五, 赵六, 钱七, 西施, 貂蝉, 王昭君, 李飞燕]
  • 例子2:将学生映射成为人
List<People> peopleList = list.stream().map(e -> new People(e.getName(), e.getGender())).collect(Collectors.toList());
for (People people : peopleList) {
    System.out.println(people);
}
// 输出结果
//        People{name='张三', gender='男'}
//        People{name='李四', gender='男'}
//        People{name='王五', gender='男'}
//        People{name='赵六', gender='男'}
//        People{name='钱七', gender='男'}
//        People{name='西施', gender='女'}
//        People{name='貂蝉', gender='女'}
//        People{name='王昭君', gender='女'}
//        People{name='李飞燕', gender='女'}

filter

filter 常用来过滤数据 (传入的参数就是过滤的规则)

  • 例子1 :过滤出所有的女生
List<Student> students = list.stream().filter(e -> "女".equals(e.getGender())).collect(Collectors.toList());
for (Student student : students) {
   System.out.println(student);
}
//        输出结果
//        Student{name='西施', gender='女', grade=100}
//        Student{name='貂蝉', gender='女', grade=100}
//        Student{name='王昭君', gender='女', grade=100}
//        Student{name='李飞燕', gender='女', grade=100}

limit

limit 一般用于截断操作 (传入的参数为截取几个)

  • 例子1:取出前3个
List<Student> students = list.stream().limit(3).collect(Collectors.toList());
for (Student student : students) {
    System.out.println(student);
}
//        输出结果
//        Student{name='张三', gender='男', grade=60}
//        Student{name='李四', gender='男', grade=70}
//        Student{name='王五', gender='男', grade=80}

skip

skip 对流进行跳过操作 (传入的参数为跳过前几个)

  • 例子:跳过前三个
List<Student> students = list.stream().skip(3).collect(Collectors.toList());
for (Student student : students) {
    System.out.println(student);
}
//        输出结果
//        Student{name='赵六', gender='男', grade=90}
//        Student{name='钱七', gender='男', grade=100}
//        Student{name='西施', gender='女', grade=100}
//        Student{name='貂蝉', gender='女', grade=100}
//        Student{name='王昭君', gender='女', grade=100}
//        Student{name='李飞燕', gender='女', grade=100}

distinct

distinct 进行去重操作 (传入的参数为去重的规则)

  • 例子:
List<Integer> collect = Stream.of(1, 2, 3, 1, 2, 3).distinct().collect(Collectors.toList());
for (Integer integer : collect) {
    System.out.println(integer);
}
//        输出结果
//        1
//        2
//        3

peek

peek 生成一个包含原Stream的所有元素的新Stream,同时会提供一个消费函数(Consumer实例),新Stream每个元素被消费的时候都会执行给定的消费函数,peek主要被用在debug用途

  • 例子
Stream.of("one", "two", "three","four").filter(e -> e.length() > 3)
                .peek(e -> System.out.println("Filtered value: " + e))
                .map(String::toUpperCase)
                .peek(e -> System.out.println("Mapped value: " + e))
                .collect(Collectors.toList());
// 输出
// Filtered value: three
// Mapped value: THREE
// Filtered value: four
// Mapped value: FOUR

sorted

sorted 常用来对流进行排序操作

  • 例子:对学生按照成绩进行倒序排序
List<Student> students = list.stream().sorted(Comparator.comparingInt(Student::getGrade).reversed()).collect(Collectors.toList());
for (Student student : students) {
    System.out.println(student);
}
//        输出结果
//        Student{name='钱七', gender='男', grade=100}
//        Student{name='西施', gender='女', grade=100}
//        Student{name='貂蝉', gender='女', grade=100}
//        Student{name='王昭君', gender='女', grade=100}
//        Student{name='李飞燕', gender='女', grade=100}
//        Student{name='赵六', gender='男', grade=90}
//        Student{name='王五', gender='男', grade=80}
//        Student{name='李四', gender='男', grade=70}
//        Student{name='张三', gender='男', grade=60}

流的终止操作

collect

转换成list Collectors.toList

List<Student> students = list.stream().filter(e -> "女".equals(e.getGender())).collect(Collectors.toList());

转换成具体的类型 Collectors.toCollection

list.stream().filter(e -> "女".equals(e.getGender())).collect(Collectors.toCollection(ArrayList::new));
        list.stream().filter(e -> "女".equals(e.getGender())).collect(Collectors.toCollection(HashSet::new));

拼接字符串 Collectors.joining

Stream<String> stream = Stream.of("hello", "world", "helloworld");
String s = stream.collect(Collectors.joining(","));
System.out.println(s);
// 输出
// hello,world,helloworld

映射 Collectors.mapping

list.stream().collect(Collectors.mapping(Student::getName, Collectors.joining("、")));

比较取小 Collectors.minBy

list.stream().collect(Collectors.minBy(Comparator.comparingInt(Student::getGrade))).get();
list.stream().min(Comparator.comparingInt(Student::getGrade)).get();

比较取大 Collectors.maxBy

list.stream().collect(Collectors.maxBy(Comparator.comparingInt(Student::getGrade))).get();
list.stream().max(Comparator.comparingInt(Student::getGrade)).get();

求和

list.stream().collect(Collectors.summarizingInt(Student::getGrade)).getSum();

求平均值

list.stream().collect(Collectors.summarizingInt(Student::getGrade)).getAverage();

分组后按照map展示

Map<String, List<Student>> collect = list.stream().collect(Collectors.groupingBy(Student::getGender));

分组计数

list.stream().collect(Collectors.groupingBy(Student::getGender, Collectors.counting()));

分组求和

list.stream().collect(Collectors.groupingBy(Student::getGender, Collectors.summingInt(Student::getGrade)));

分组求平均

list.stream().collect(Collectors.groupingBy(Student::getGender, Collectors.averagingInt(Student::getGrade)));

分组后取最大

list.stream().collect(Collectors.groupingBy(Student::getGender, Collectors.maxBy(Comparator.comparingInt(Student::getGrade))));

分组后取最小

list.stream().collect(Collectors.groupingBy(Student::getGender, Collectors.minBy(Comparator.comparingInt(Student::getGrade))));

将结果转换成Map Collectors.toMap

可能会导致key重复的情况,需自行配置规则防止重复key报错。

Map<String, Student> collect = list.stream().collect(Collectors.toMap(Student::getName, v -> v, (o1, o2) -> o1));

forEach

迭代流中的每一个数据,等同于for循环

List<String> items = Arrays.asList("a","b","c","d","e");
items.forEach(item->System.out.println(item));
//输出 a,b,c,d,e

find

  • findAny查找任何一个就返回 Optional
List<String> strings = Arrays.asList("abc", "dd", "DD", "dd", "abcd","cc", "jkl");
String result = strings.stream().filter(str -> str.equals("dd"))
                .findAny()
                .orElse(null);
System.out.println(result);
//输出 dd

  • findFirst查找到第一个就返回 Optional
List<String> strings = Arrays.asList("abc", "dd", "DD", "dd", "abcd","cc", "jkl");
String result = strings.stream().filter(str -> str.equals("dd"))
                .findFirst()
                .orElse(null);
System.out.println(result);
//输出 dd

  • anyMatch匹配上任何一个则返回Boolean
List<String> strings = Arrays.asList("abc", "dd", "DD", "dd", "abcd","cc", "jkl");
Boolean result = strings.stream().anyMatch(str -> str.equals("dd"));
System.out.println(result);
//输出 true

  • allMatch匹配所有的元素则返回Boolean
List<String> strings = Arrays.asList("abc", "dd", "DD", "dd", "abcd","cc", "jkl");
Boolean result = strings.stream().allMatch(str -> str.equals("dd"));
System.out.println(result);
//输出 false

  • noneMatch检查在所需位置是否没有带有必需字符的元素,返回Boolean
List<String> strings = Arrays.asList("abc", "dd", "DD", "dd", "abcd","cc", "jkl");
Boolean result = strings.stream().noneMatch(str -> str.equals("ff"));
System.out.println(result);
//输出 true

reduce

它可以把一个Stream的所有元素按照聚合函数聚合成一个结果

// 0代表初始值 如果不传0 则使用第一个元素作为初始值,acc是计算值,n 是每个元素
int sum = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).reduce(0, (acc, n) -> acc + n);
System.out.println(sum); // 45

//不传初始值的情况下,返回的是Optional类型的结果
List<Integer> numList = Arrays.asList(1,2,3,4,5);
Optional<Integer> result = numList.stream().reduce((a, b) -> a + b);
System.out.println(result.get());

JavaStream常用方法包括获取Stream间方法和终结方法。 获取Stream的方法有两种:集合获取Stream和数组获取Stream。集合获取Stream可以使用集合类的stream()方法,例如Map的keySet()方法可以获取键,values()方法可以获取值,entrySet()方法可以获取键值对。数组获取Stream可以使用Arrays类的stream()方法,将数组转换为Stream间方法是对Stream进行操作的方法,一次操作完毕之后,还可以继续进行其他操作常用间方法包括filter()、map()、flatMap()、distinct()、sorted()、limit()和skip()等。filter()方法用于过滤元素,map()方法用于对元素进行映射,flatMap()方法用于扁平化处理,distinct()方法用于去重,sorted()方法用于排序,limit()方法用于限制元素数量,skip()方法用于跳过元素。 终结方法是Stream的最后一个操作,一个Stream只能有一个终结方法。常用的终结方法包括forEach()、collect()、count()、min()、max()、reduce()和toArray()等。forEach()方法用于遍历元素,collect()方法用于将元素收集到集合,count()方法用于统计元素数量,min()方法用于获取最小值,max()方法用于获取最大值,reduce()方法用于对元素进行归约操作,toArray()方法用于将元素转换为数组。 综合应用Stream常用方法可以实现对数据的筛选、转换、排序、统计等操作,提高代码的简洁性和可读性。 #### 引用[.reference_title] - *1* *2* *3* [Java 基础进阶篇(十二):Stream 常用方法总结](https://blog.csdn.net/weixin_43819566/article/details/130537949)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值