首页 > 其他分享 >第十一章 对Stream流的聚合函数处理

第十一章 对Stream流的聚合函数处理

时间:2024-11-18 23:43:34浏览次数:3  
标签:聚合 name Stream int 第十一章 age score Student public

目录

一、对流中数据进行聚合计算

二、对流中数据进行分组

三、对流中数据进行多级分组

四、对流中数据进行分区 

4.1. 使用方式及代码

4.2. 分区于分组的区别

分区(Partitioning)

分组(Grouping)

实际应用场景

五、对流中数据进行拼接


一、对流中数据进行聚合计算

当我们使用Stream流处理数据后,可以像数据库的聚合函数一样对某个字段进行操作。比如获取最大值,获取最小值,求总和,平均值,统计数量。

package com.wzx;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Test {
    public static void main(String[] args) {
        Stream<Student> studentStream = Stream.of(
                new Student("赵丽颖", 58, 95),
                new Student("杨颖", 56, 88),
                new Student("迪丽热巴", 56, 99),
                new Student("柳岩", 52, 77));
                // 获取最大值
                Optional<Student> collect1 = studentStream.collect(Collectors.maxBy((o1, o2) ->
                        o1.getScore() - o2.getScore()));
                System.out.println(collect1.get());
                // 获取最小值
                Optional<Student> collect2 = studentStream.collect(Collectors.minBy((o1, o2) ->
                        o1.getScore() - o2.getScore()));
                System.out.println(collect2.get());
                // 求总和
                int sumAge = studentStream.collect(Collectors.summingInt(s -> s.getAge()));
                System.out.println("sumAge = " + sumAge);
                // 平均值
                double avgScore = studentStream.collect(Collectors.averagingInt(s -> s.getScore()));
                System.out.println("avgScore = " + avgScore);
                // 统计数量
                Long count = studentStream.collect(Collectors.counting());
                System.out.println("count = " + count);
    }
}

class Student {
    private String name;
    private int age;
    private int score;
    public Student() {}
    public Student(String name, int age, int score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }
}

二、对流中数据进行分组

当我们使用Stream流处理数据后,可以根据某个属性将数据分组:

package com.wzx;

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

public class Test {
    public static void main(String[] args) {
        Stream<Student> studentStream1 = Stream.of(
            new Student("赵丽颖", 52, 95),
            new Student("杨颖", 56, 88),
            new Student("迪丽热巴", 56, 55),
            new Student("柳岩", 52, 33));
        Map<Integer, List<Student>> map1 = studentStream1.collect(Collectors.groupingBy(Student::getAge));
        map1.forEach((k, v) -> {
            System.out.println(k + "::" + v);
        });

        Stream<Student> studentStream2 = Stream.of(
                new Student("赵丽颖", 52, 95),
                new Student("杨颖", 56, 88),
                new Student("迪丽热巴", 56, 55),
                new Student("柳岩", 52, 33));
        // 将分数大于60的分为一组,小于60分成另一组
        Map<String, List<Student>> map2 = studentStream2.collect(Collectors.groupingBy((s) ->
        {
            if (s.getScore() > 60) {
                return "及格";
            } else {
                return "不及格";
            }
        }));
        map2.forEach((k, v) -> {
            System.out.println(k + "::" + v);
        });
    }
}

class Student {
    private String name;
    private int age;
    private int score;
    public Student() {}
    public Student(String name, int age, int score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }
}

运行输出结果:

三、对流中数据进行多级分组

package com.wzx;

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

public class Test {
    public static void main(String[] args) {
        Stream<Student> studentStream = Stream.of(
            new Student("赵丽颖", 52, 95),
            new Student("杨颖", 56, 88),
            new Student("迪丽热巴", 56, 99),
            new Student("柳岩", 52, 77));
        Map<Integer, Map<String, List<Student>>> map =
            studentStream.collect(Collectors.groupingBy(s -> s.getAge(), Collectors.groupingBy(s -> {
                if (s.getScore() >= 90) {
                    return "优秀";
                } else if (s.getScore() >= 80 && s.getScore() < 90) {
                    return "良好";
                } else if (s.getScore() >= 80 && s.getScore() < 80) {
                    return "及格";
                } else {
                    return "不及格";
                }
            })));
        map.forEach((k, v) -> {
            System.out.println(k + " == " + v);
        });
    }
}

class Student {
    private String name;
    private int age;
    private int score;
    public Student() {}
    public Student(String name, int age, int score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }
}

运行输出效果:

四、对流中数据进行分区 

4.1. 使用方式及代码

Collectors.partitioningBy 会根据值是否为true,把集合分割为两个列表,一个true列表,一个false列表。

package com.wzx;

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

public class Test {
    public static void main(String[] args) {
        Stream<Student> studentStream = Stream.of(
                new Student("赵丽颖", 52, 95),
                new Student("杨颖", 56, 88),
                new Student("迪丽热巴", 56, 99),
                new Student("柳岩", 52, 77));
        // partitioningBy会根据值是否为true,把集合分割为两个列表,一个true列表,一个false列表。
        Map<Boolean, List<Student>> map = studentStream.collect(Collectors.partitioningBy(s ->
                s.getScore() > 90));
        map.forEach((k, v) -> {
            System.out.println(k + " == " + v);
        });
    }
}

class Student {
    private String name;
    private int age;
    private int score;
    public Student() {}
    public Student(String name, int age, int score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }
}

运行输出结果,可以明显看到分区输出结果是一个数组:

4.2. 分区于分组的区别

Stream流的分区和分组是两种不同的操作,它们在数据处理上有明显的区别。

分区(Partitioning)

分区操作是将流中的元素根据某个条件分成两个或多个子流。分区操作的结果是一个流,而不是一个集合。例如,可以使用分区操作将学生按照分数高低分成两个子流:高分和低分。分区操作通常使用partitioningBy方法实现,该方法返回一个Map,其中键是分区条件,值是对应的流‌1。

分组(Grouping)

分组操作是将流中的元素按照某个分类函数分成不同的组。分组操作的结果是一个Map,其中键是分类函数返回的值,值是具有该分类值的元素的列表。例如,可以使用分组操作将交易记录按照货币类型分成不同的组,每组包含所有相同货币类型的交易记录‌1。分组操作通常使用groupingBy方法实现。

实际应用场景

  • 分区‌:适用于需要将数据分成两个或多个子集进行进一步处理的场景。例如,将学生按照分数高低分成两个子流,然后对每个子流进行不同的处理。
  • 分组‌:适用于需要将数据按照某个属性进行分类汇总的场景。例如,将交易记录按照货币类型分组,以便进行统计和分析。

五、对流中数据进行拼接

Collectors.joining 会根据指定的连接符,将所有元素连接成一个字符串。

package com.wzx;

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

public class Test {
    public static void main(String[] args) {
        Stream<Student> studentStream = Stream.of(
                new Student("赵丽颖", 52, 95),
                new Student("杨颖", 56, 88),
                new Student("迪丽热巴", 56, 99),
                new Student("柳岩", 52, 77));
        String collect = studentStream
                .map(Student::getName)
                .collect(Collectors.joining(">_<", "^_^", "^v^"));
        System.out.println(collect);
    }
}

class Student {
    private String name;
    private int age;
    private int score;
    public Student() {}
    public Student(String name, int age, int score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }
}

运行输出结果:

 

标签:聚合,name,Stream,int,第十一章,age,score,Student,public
From: https://blog.csdn.net/qushaming/article/details/143869603

相关文章

  • Gradio 和 Streamlit 安装与使用教程
    最近SealosDevbox有点火......
  • java day13 Set集合 & Map集合 & Stream流
    目录​编辑1.Set集合: 1.Set集合的特点:  2.HashSet的底层原理:​编辑  3.LinkedHashSet集合的底层原理:  4.TreeSet集合:2.Map集合: 1.Map集合概述: 2.Map集合的常用方法:3.Map集合的遍历方式:  4.Map集合的实现类:3.Stream流:1.获取流的方法:2.流......
  • 『玩转Streamlit』--图像与媒体组件
    Streamlit中的图像与媒体组件,主要是st.image、st.audio和st.video。它们是专为在StreamlitWeb应用程序中嵌入和展示多媒体内容而设计的,这些组件不仅丰富了应用程序的呈现形式,还极大地提升了用户体验和互动性。1.st.imagest.image函数用于在Streamlit应用程序中展示图像内容,增......
  • streamstring类介绍
    std::stringstream是C++标准库中提供的一个类,定义在头文件<sstream>中。它是基于字符串的流(stream),允许像操作输入流(std::cin)或输出流(std::cout)那样,操作字符串内容。std::stringstream是std::iostream的派生类,支持同时进行字符串解析(输入)和字符串构造(输出)。核心概念std:......
  • Stream流统计集合元素出现次数并降序
    使用Arrays.stream()结合Collectors.groupingBy()和Collectors.counting()来统计数组中每个元素出现个数,按照出现次数降序排列后获取前五个元素及其出现次数的示例代码:importjava.util.*;importjava.util.stream.Collectors;publicclassArrayElementCountTopFive{......
  • Unable to load io.netty.resolver.dns.macos.MacOSDnsServerAddressStreamProvider,
     macm1启动项目,报错,“Unabletoloadio.netty.resolver.dns.macos.MacOSDnsServerAddressStreamProvider,fallbacktosystemdefaults.ThismayresultinincorrectDNSresolutionsonMacOS.”,出现这个问题是因为使用了spring-cloud-starter-gateway依赖,这需要额外安装......
  • 链路聚合Link Aggregation
    简介链路聚合是一种将多条链路捆绑在一起成为一条逻辑链路,从而增加链路带宽的目的,本技术华为叫以太网链路聚合Eth-Trunk,华三叫bridge-aggregation原理相关概念聚合组(LinkAggregationGroup,LAG):若干条链路捆绑在一起所形成的的逻辑链路。每个聚合组唯一对应着一个逻辑接口,这......
  • cmu15545笔记-排序和聚合算法(Sorting&Aggregation Algorithms)
    目录概述排序堆排序外部归并排序使用索引聚合操作排序聚合哈希聚合概述本节和下一节讨论具体的操作算子,包括排序,聚合,Join等。排序为什么需要排序操作:关系型数据库是无序的,但是使用时往往需要顺序数据(OrderedBy,GroupBy,Distinct)。主要矛盾:磁盘很大:要排序的数据集很大,内......
  • HDMI规范-第十一章 HEAC
    1.简介HEAC技术是HDMI接口的一部分,旨在提供以太网连接和音频回传功能。HEAC通过HEAC-和HEAC+线对或仅通过HEAC+线实现数据传输。此技术分为两部分:HEC(HDMI以太网通道)和ARC(音频回传通道)。HEC 使用差分模式下的MLT-3信令,允许源设备和接收设备之间进行100BASE-TX数据的全双工......
  • 『玩转Streamlit』--数据展示组件
    数据展示组件在Streamlit各类组件中占据了至关重要的地位,它的核心功能是以直观、易于理解的方式展示数据。本次介绍的数据展示组件st.dataframe和st.table,能够将复杂的数据集以表格、图表等形式清晰地呈现出来,使得用户能够快速把握数据的整体情况和细节特征。1.st.dataframes......