首页 > 编程语言 >Java Stream基本用法

Java Stream基本用法

时间:2024-10-16 10:17:51浏览次数:8  
标签:Java Stream stream List 用法 Stu add new stuId

介绍

Java Stream是Java 8中引入的一个新的抽象概念,它允许以声明式的方式处理数据集合。Stream将要处理的元素集合视为一种流,在流的过程中,可以利用Stream API对元素进行各种操作,如筛选、排序、聚合等。Stream操作可以分为中间操作和终端操作,中间操作每次返回一个新的流,可以有多个,而终端操作则产生一个结果或一个新的集合

创建list集合数据

List<Stu> stuData(){
    List<Stu> stuList = new ArrayList<>();
    stuList.add(new Stu(1,"张安",20));
    stuList.add(new Stu(2,"李四",38));
    stuList.add(new Stu(3,"王五",19));
    stuList.add(new Stu(4,"赵六",76));
    return stuList;
}
//科目数据
List<Course> courseList(){
    List<Course> courseList = new ArrayList<>();
    courseList.add(new Course(1,"语文"));
    courseList.add(new Course(2,"数学"));
    courseList.add(new Course(3,"英语"));
    return courseList;
}


//成绩数据
List<Score> scoreData(){
    List<Score> scoreList = new ArrayList<>();
    scoreList.add(new Score(1,1,80));
    scoreList.add(new Score(1,2,90));
    scoreList.add(new Score(1,3,70));
    scoreList.add(new Score(2,1,79));
    scoreList.add(new Score(2,2,98));
    scoreList.add(new Score(2,3,78));
    scoreList.add(new Score(3,1,98));
    scoreList.add(new Score(3,2,76));
    scoreList.add(new Score(3,3,88));
    scoreList.add(new Score(4,1,99));
    return scoreList;
}

使用stream条件输出

/**
 * stream条件输出
 * 判断条件: 张三
 * */
@Test
void streamPrintOut(){
    List<Stu> list = stuData();
    list.stream()
            .filter(stu -> "张安".equals(stu.getStuName()))
            .forEach(System.out::println);
            //Stu(stuId=1, stuName=张安, stuAge=20)
}

统计

/**
 * 统计
 * 条件:年龄大于20岁
 * */
@Test
void ageGtCount(){
    List<Stu> list = stuData();
    long count = list.stream().filter(stu -> stu.getStuAge()>20).count();
    System.out.println(count);// 2
}

排序

正序

/**
 * 年龄排序
 * 正序
 * */
@Test
void ageSort(){
    List<Stu> list = stuData();
    list.stream()
            .sorted(Comparator.comparing(Stu::getStuAge))
            .forEach(System.out::println);
    //Stu(stuId=3, stuName=王五, stuAge=19)
    //Stu(stuId=1, stuName=张安, stuAge=20)
    //Stu(stuId=2, stuName=李四, stuAge=38)
    //Stu(stuId=4, stuName=赵六, stuAge=76)
}

倒序

/**
 * 年龄排序
 * 倒序
 * */
@Test
void ageSort(){
    List<Stu> list = stuData();
    list.stream()
            .sorted(Comparator.comparing(Stu::getStuAge).reversed())
            .forEach(System.out::println);
    //Stu(stuId=4, stuName=赵六, stuAge=76)
    //Stu(stuId=2, stuName=李四, stuAge=38)
    //Stu(stuId=1, stuName=张安, stuAge=20)
    //Stu(stuId=3, stuName=王五, stuAge=19)
}

去重

/**
 * 名字去重
 * */
@Test
void distinct(){
    List<Stu> list = stuData();
    list.add(new Stu(5,"张三",23));
    list.add(new Stu(6,"赵六",45));
    list.add(new Stu(7,"王五",43));
    list.stream().map(Stu::getStuName).distinct().forEach(System.out::println);
    //张安
    //李四
    //王五
    //赵六
    //张三
}

map

/**
 * map
 * 年龄相加
 * */
@Test
void map(){
    List<Stu> list = stuData();
    list.stream()
            .map(stu -> stu.getStuAge() + stu.getStuAge())
            .forEach(System.out::println);
    //40
    //76
    //38
    //152
}

summaryStatistics

/**
 * 函数统计
 * */
@Test
void function(){
    List<Stu> list = stuData();
    IntSummaryStatistics state = list.stream()
            .mapToInt(Stu::getStuAge)
            .summaryStatistics();
    System.out.println("最大年龄:"+state.getMax());//最大年龄:76
    System.out.println("最小年龄:"+state.getMin());//最小年龄:19
    System.out.println("总年龄:"+state.getSum());//总年龄:153
    System.out.println("平均年龄:"+state.getAverage());//平均年龄:38.25
    System.out.println("数量:"+state.getCount());//数量:4
}

分组

/**
 * 分组
 * */
@Test
void group(){
    List<Stu> list = stuData();
    list.add(new Stu(5,"张三",23));
    list.add(new Stu(6,"赵六",45));
    list.add(new Stu(7,"王五",43));
    Map<String, List<Stu>> collect = list.stream().collect(Collectors.groupingBy(Stu::getStuName));
    System.out.println(collect);
    //{
    //  李四=[Stu(stuId=2, stuName=李四, stuAge=38)], 
    //  张三=[Stu(stuId=5, stuName=张三, stuAge=23)], 
    //  张安=[Stu(stuId=1, stuName=张安, stuAge=20)], 
    //  王五=[Stu(stuId=3, stuName=王五, stuAge=19), Stu(stuId=7, stuName=王五, stuAge=43)], 
    //  赵六=[Stu(stuId=4, stuName=赵六, stuAge=76), Stu(stuId=6, stuName=赵六, stuAge=45)]
    // }
}

join联查

/**
 * stream两表联查
 * */
@Test
void join(){
    List<Score> scoreList = scoreData();
    List<StuInfo> infoList = scoreList.stream().map(score -> {
        List<Stu> stuList = stuData();//获取学生表的数据
        Stu stu = stuList.stream()
                .filter(stus -> stus.getStuId().equals(score.getStuId()))//根据score表中的stuId查询
                .distinct().findFirst().get();//获取单个对象
        StuInfo stuInfo = new StuInfo();//中间表
        BeanUtils.copyProperties(stu, stuInfo);//拷贝
        stuInfo.setScore(score.getScore());
        stuInfo.setScoreId(score.getScore());
        return stuInfo;
    }).collect(Collectors.toList());
    infoList.forEach(System.out::println);
    //StuInfo(stuId=1, stuName=张安, scoreId=80, score=80)
    //StuInfo(stuId=1, stuName=张安, scoreId=90, score=90)
    //StuInfo(stuId=1, stuName=张安, scoreId=70, score=70)
    //StuInfo(stuId=2, stuName=李四, scoreId=79, score=79)
    //StuInfo(stuId=2, stuName=李四, scoreId=98, score=98)
    //StuInfo(stuId=2, stuName=李四, scoreId=78, score=78)
    //StuInfo(stuId=3, stuName=王五, scoreId=98, score=98)
    //StuInfo(stuId=3, stuName=王五, scoreId=76, score=76)
    //StuInfo(stuId=3, stuName=王五, scoreId=88, score=88)
    //StuInfo(stuId=4, stuName=赵六, scoreId=99, score=99)
}

多表联查

/**
 * stream三表联查
 * */
@Test
void join(){
    List<Score> scoreList = scoreData();
    List<StuInfo> infoList = scoreList.stream().map(score -> {
        Stu stu = stuData().stream()
                .filter(stus -> stus.getStuId().equals(score.getStuId()))//根据score表中的stuId查询
                .distinct()//去重
                .findFirst().get();//获取单个对象
        StuInfo stuInfo = new StuInfo();//中间表
        BeanUtils.copyProperties(stu, stuInfo);//拷贝
        stuInfo.setScore(score.getScore());
        stuInfo.setScoreId(score.getScore());
        Course courses = courseList().stream()
                .filter(course -> course.getCourseId().equals(score.getCourseId()))//根据score表中courseId查询
                .distinct()
                .findFirst().get();
        stuInfo.setCourseName(courses.getCourseName());
        return stuInfo;
    }).collect(Collectors.toList());
    infoList.forEach(System.out::println);
}

输出

stream组合查询

计算各个学生总成绩

/**
 * 学生总成绩
 * */
@Test
void sumSort(){
    Map<Integer, Integer> averageScore = scoreData().stream()
            .collect(Collectors.groupingBy(
                    Score::getStuId,
                    Collectors.summingInt(Score::getScore)));
    System.out.println(averageScore);//{1=240, 2=255, 3=262, 4=99}
    //根学生信息连接
    List<StuInfo> infoList = averageScore.entrySet().stream().map(entry -> {
        Integer stuId = entry.getKey();//学生id
        Integer sum = entry.getValue();//总成绩
        //获取学生信息
        Stu stuData = stuData().stream().filter(stu -> stu.getStuId().equals(stuId)).findFirst().get();
        StuInfo stuInfo = new StuInfo();
        stuInfo.setSum(sum);
        stuInfo.setStuName(stuData.getStuName());
        stuInfo.setStuId(stuData.getStuId());
        return stuInfo;
    }).collect(Collectors.toList());
    infoList.forEach(System.out::println);
}

平均分

/**
 * 学生平均分
 * */
@Test
void average(){
    Map<Integer, Double> average = scoreData().stream()
            .collect(Collectors.groupingBy(
                    Score::getStuId,
                    Collectors.averagingDouble(Score::getScore)));
    System.out.println(average);//{1=80.0, 2=85.0, 3=87.33333333333333, 4=99.0}
    List<StuInfo> infoList = average.entrySet().stream().map(entry -> {
        Integer stuId = entry.getKey();//学生id
        Double avg = entry.getValue();//平均分
        Stu stuData = stuData().stream().filter(stu -> stu.getStuId().equals(stuId)).findFirst().get();
        StuInfo stuInfo = new StuInfo();
        stuInfo.setAvg(avg);
        stuInfo.setStuName(stuData.getStuName());
        stuInfo.setStuId(stuData.getStuId());
        return stuInfo;
    }).collect(Collectors.toList());
    infoList.forEach(System.out::println);
}

平均分+倒排序

/**
 * 学生平均分
 * */
@Test
void average(){
    Map<Integer, Double> average = scoreData().stream()
            .collect(Collectors.groupingBy(
                    Score::getStuId,
                    Collectors.averagingDouble(Score::getScore)));
    System.out.println(average);//{1=80.0, 2=85.0, 3=87.33333333333333, 4=99.0}
    List<StuInfo> infoList = average.entrySet().stream().map(entry -> {
        Integer stuId = entry.getKey();//学生id
        Double avg = entry.getValue();//平均分
        Stu stuData = stuData().stream().filter(stu -> stu.getStuId().equals(stuId)).findFirst().get();
        StuInfo stuInfo = new StuInfo();
        stuInfo.setAvg(avg);
        stuInfo.setStuName(stuData.getStuName());
        stuInfo.setStuId(stuData.getStuId());
        return stuInfo;
    }).sorted(Comparator.comparing(StuInfo::getAvg).reversed()).collect(Collectors.toList());
    infoList.forEach(System.out::println);
}

概率

/**
 * 学生考试成绩是否及格的占比,按照90分为标准
 * */
@Test
void pass(){
    int total = scoreData().size();//总参加考试次数
    //成绩大于90分
    long passCount = scoreData().stream().filter(score -> score.getScore() >= 90).count();
    //未及格人数
    long failCount = total - passCount;
    double pass =  (double) passCount / total * 100;
    double fail =  (double) failCount / total * 100;
    System.out.println("及格率:"+pass+"%");//及格率:40.0%
    System.out.println("不及格率:"+fail+"%");//不及格率:60.0%
}

分组统计

/**
 * 统计每门课程的学生选修人数
 * */
@Test
void countCourse(){
    //统计选修课数量
    Map<Integer, Long> collect = scoreData().stream().collect(Collectors.groupingBy(Score::getCourseId, Collectors.counting()));
    System.out.println(collect);//{1=4, 2=3, 3=3}
    List<CourseInfo> courseInfos = collect.entrySet().stream().map(entry -> {
        Integer courseId = entry.getKey();//科目id
        Long count = entry.getValue();//选修数量
        Course courseData = courseList().stream().filter(course -> course.getCourseId().equals(courseId)).findFirst().get();
        CourseInfo courseInfo = new CourseInfo();
        courseInfo.setCount(count);
        courseInfo.setCourseName(courseData.getCourseName());
        return courseInfo;
    }).collect(Collectors.toList());
    courseInfos.forEach(System.out::println);
}

计算金额

/**
 * 初始化用户数据
 * */
public List<User> initUser(){
    List<User> users = new ArrayList<>();
    users.add(new User(1,"张三"));
    users.add(new User(2,"李四"));
    users.add(new User(3,"王五"));
    return users;
}


/**
 * 初始化银行卡数据
 * */
public List<Bank> initBank(){
    List<Bank> banks = new ArrayList<>();
    banks.add(new Bank(1,BigDecimal.valueOf(3000),1));
    banks.add(new Bank(2,BigDecimal.valueOf(8000),1));
    banks.add(new Bank(3,BigDecimal.valueOf(12000),3));
    banks.add(new Bank(4,BigDecimal.valueOf(93000),3));
    banks.add(new Bank(5,BigDecimal.valueOf(53000),2));
    return banks;
}


/**
 * 计算该银行总金额
 * */
@Test
public void totalMoney(){
    BigDecimal reduce = initBank().stream().map(Bank::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
    System.out.println(reduce);//169000
}


/**
 * 计算每个用户的总存款
 * */
@Test
public void deposit(){
    Map<Integer, BigDecimal> banks = initBank().stream()
            .collect(Collectors.toMap(
                    Bank::getUserId,
                    bank -> BigDecimal.ONE.multiply(bank.getMoney()),
                    BigDecimal::add));
    System.out.println(banks);//{1=11000, 2=53000, 3=105000}
    List<UserInfo> infoList = banks.entrySet().stream()
            .map(entry -> {
                Integer userId = entry.getKey();//用户id
                BigDecimal amount = entry.getValue();//用户总金额
                User userData = initUser().stream().filter(user -> user.getUserId().equals(userId))
                        .findFirst().get();
                UserInfo userInfo = new UserInfo();
                userInfo.setAmount(amount);
                userInfo.setUsername(userData.getUserName());
                return userInfo;
            }).collect(Collectors.toList());
    infoList.forEach(System.out::println);
}

总结 

Java Stream流,在java8后,我们可以会经常使用,提高了我们代码的美观,以及提高性能的效率,完美的将之前几十行上百行的操作或计算代码,用简单几行完成,同样,他可以集合mybatis-plus来完成许多sql查询,以及多表联查,我之前发过一篇mybatis-plus-join的文章,里面详细的描述了mybatis-plus的联查方式,但是我们在面对大量数据时,使用join连查还是会导致性能的下降,所以可以通过stream流来提升,过段时间,我还会出一期stream流+mybatis-plus联查。

标签:Java,Stream,stream,List,用法,Stu,add,new,stuId
From: https://blog.csdn.net/yxhsk8/article/details/142903517

相关文章

  • java计算机毕业设计共享电动车电池管理系统设计与实现(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、研究背景随着城市交通的日益拥堵以及人们对环保出行方式需求的增长,共享电动车逐渐成为城市交通体系中的重要组成部分。共享电动车的普及带来了便捷,但同时......
  • java计算机毕业设计爱心互助及物品回收管理系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、研究背景在现代社会,随着人们生活水平的提升以及消费的不断增长,物品的更新换代日益频繁,这导致了大量闲置物品的产生。与此同时,社会上还存在许多需要帮助的......
  • java计算机毕业设计汉服文化交流平台(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着中华文化的复兴,汉服作为传统文化的重要载体,正逐渐从历史的尘埃中走出,焕发出新的生机。近年来,汉服爱好者群体迅速扩大,他们不仅在日常生活中穿着汉......
  • 「Java开发指南」MyEclipse for Spring参考篇——参数
    MyEclipsev2024.1离线版下载MyEclipse技术交流群:742336981欢迎一起进群讨论1.代码生成注意:Spring搭建需要MyEclipseSpring或Bling授权。该面板控制当前MyEclipse工作区的Spring代码生成参数。代码生成参数2.自定义该面板控制当前MyEclipse工作区的自定义参数。......
  • Java 初学 day09
    java091、形式参数基本类型:当基本数据类型作为参数传递的时候,传递是具体的数值引用类型:数组:当数组作为方法的参数类型的时候,将来需要传递数组的地址值具体的类:当你看到一个类作为方法的参数类型的时候,将来调用需要传入该类或该类的子类的对象抽象类:当你看到......
  • Mybatis-plus 3.5.4 的AOP问题 java.lang.ClassCastException: class org.springfram
    报错,然后我把mapper上的@repository删掉就好了,为什么ChatGPT说:ChatGPT删除@Repository注解后问题解决,可能是与SpringAOP代理机制和MyBatisPlus结合时的一些细节有关。以下是原因分析:@Repository和SpringAOP代理的影响@Repository注解的主要作用是将类标记为持......
  • 个人Stream常用操作
    1、list转map我们可以使用Collectors.toMap()方法来实现。Person对象类@Data@Builder@AllArgsConstructor@NoArgsConstructorpublicclassPerson{privateStringname;//姓名privateintsalary;//薪资privateintage;//年龄privateStr......
  • Java最全面试->Java基础->JavaSE->基础语法
    基础语法下边是我自己整理的面试题,基本已经很全面了,想要的可以私信我,我会不定期去更新思维导图哪里不会点哪里基本数据类型和方位修饰符数据类型有哪些基本数据类型byte、int、short、long、float、double、boolean、char引用数据类型类、数组、接口访问权限修饰符......
  • java计算机毕业设计IT培训机构教务管理系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着信息技术的迅猛发展,IT培训机构在教育领域中的地位越来越重要。这些机构通常提供各种计算机相关的培训课程,旨在培养学生的实践能力和专业素养。......
  • java计算机毕业设计高校失物招领系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容高校失物招领系统的研究背景、意义和目的在当代高校生活中,失物招领是一个常见但又极其重要的问题。随着高校规模的不断扩大和学生人数的增多,校园内遗失物品的......