java8流操作之不常用但是很好用的隐藏api

news2024/11/18 0:20:04

前言

1、一些普通的方式就不再多说了,这里主要说一些不常用的,但是作用很大的api方式

2、如果想要细致了解可以参考 JAVA8的流操作,十分推荐

一、flatMap

1、这个api主要是用来推平流的,和map不一致,map是对象到对象,而flatMap是把流平坦出来,具体如下,看注释就能明白了

2、我们看看 flatMap 展开或者叫扁平化操作,相当于 map+flat,通过 map 把每一个元素替换为一个流,然后展开这个流。比如,我们要统计所有订单的总价格,可以有两种方式:

  • 直接通过原始商品列表的商品个数 * 商品单价统计的话,可以先把订单通过 flatMap 展开成商品清单,也就是把 Order 替换为 Stream,然后对每一个 OrderItem 用 mapToDouble 转换获得商品总价,最后进行一次 sum 求和;
  • 利用 flatMapToDouble 方法把列表中每一项展开替换为一个 DoubleStream,也就是直接把每一个订单转换为每一个商品的总价,然后求和
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static java.util.Comparator.comparingDouble;
import static java.util.stream.Collectors.*;

class Scratch {
    public static void main(String[] args) {

        // 这种方式可以避免 两次的for循环,如果不这样,你得先遍历外层的order的list,再挨个遍历每隔order下的item。
        List<Order> orders = new ArrayList<>();
        //直接展开订单商品进行价格统计
        System.out.println(orders.stream()
                .flatMap(order -> order.getOrderItemList().stream())
                .mapToDouble(item -> item.getProductQuantity() * item.getProductPrice()).sum());

        //另一种方式flatMap+mapToDouble=flatMapToDouble
        System.out.println(orders.stream()
                .flatMapToDouble(order ->
                        order.getOrderItemList()
                                .stream().mapToDouble(item -> item.getProductQuantity() * item.getProductPrice()))
                .sum());
	}
}

@Data
class Order {
    private Long id;

    private Long customerId;//顾客ID

    private String customerName;//顾客姓名

    private List<OrderItem> orderItemList;//订单商品明细

    private Double totalPrice;//总价格

    private LocalDateTime placedAt;//下单时间

}

//订单商品类
@Data
@AllArgsConstructor
@NoArgsConstructor
class OrderItem {

    private Long productId;//商品ID

    private String productName;//商品名称

    private Double productPrice;//商品价格

    private Integer productQuantity;//商品数量

}

二、groupBy

1、基础操作说明这里就不再多说了,主要说的就说一些稍微不怎么用到的,但是其实作用很大的方式。

2、 groupBy 是分组统计操作,类似 SQL 中的 group by 子句。它和后面介绍的 partitioningBy 都是特殊的收集器,同样也是终结操作。分组操作比较复杂,为帮助大家理解得更透彻,我准备了 8 个案例


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static java.util.Comparator.comparingDouble;
import static java.util.stream.Collectors.*;

class Scratch {
    public static void main(String[] args) {

        //按照用户名分组,统计下单数量
        List<Map.Entry<String, Long>> collect1 = orders.stream().collect(groupingBy(Order::getCustomerName, counting()))
                .entrySet().stream().sorted(Map.Entry.<String, Long>comparingByValue().reversed()).collect(toList());
        System.out.println(collect1);


        //按照用户名分组,统计订单总金额
        System.out.println(orders.stream().collect(groupingBy(Order::getCustomerName, summingDouble(Order::getTotalPrice)))
                .entrySet().stream().sorted(Map.Entry.<String, Double>comparingByValue().reversed()).collect(toList()));


        //按照用户名分组,统计商品采购数量
        System.out.println(orders.stream().collect(groupingBy(Order::getCustomerName,
                        summingInt(
                                order -> order.getOrderItemList().stream()
                                .collect(summingInt(OrderItem::getProductQuantity))
                        )))
                .entrySet().stream().sorted(Map.Entry.<String, Integer>comparingByValue().reversed()).collect(toList()));


        //统计最受欢迎的商品,倒序后取第一个
        orders.stream()
                .flatMap(order -> order.getOrderItemList().stream())
                .collect(groupingBy(OrderItem::getProductName, summingInt(OrderItem::getProductQuantity)))
                .entrySet().stream()
                .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
                .map(Map.Entry::getKey)
                .findFirst()
                .ifPresent(System.out::println);


        //统计最受欢迎的商品的另一种方式,直接利用maxBy
        orders.stream()
                .flatMap(order -> order.getOrderItemList().stream())
                .collect(groupingBy(OrderItem::getProductName, summingInt(OrderItem::getProductQuantity)))
                .entrySet().stream()
                .collect(maxBy(Map.Entry.comparingByValue()))
                .map(Map.Entry::getKey)
                .ifPresent(System.out::println);


        //按照用户名分组,选用户下的总金额最大的订单
        orders.stream().collect(groupingBy(Order::getCustomerName, collectingAndThen(maxBy(comparingDouble(Order::getTotalPrice)), Optional::get)))
                .forEach((k, v) -> System.out.println(k + "#" + v.getTotalPrice() + "@" + v.getPlacedAt()));


        //根据下单年月分组,统计订单ID列表
        System.out.println(orders.stream().collect
                (groupingBy(order -> order.getPlacedAt().format(DateTimeFormatter.ofPattern("yyyyMM")),
                        mapping(order -> order.getId(), toList()))));


        //根据下单年月+用户名两次分组,统计订单ID列表
        System.out.println(orders.stream().collect
                (groupingBy(order -> order.getPlacedAt().format(DateTimeFormatter.ofPattern("yyyyMM")),
                        groupingBy(order -> order.getCustomerName(),
                                mapping(order -> order.getId(), toList())))));
    }
}

@Data
class Order {
    private Long id;

    private Long customerId;//顾客ID

    private String customerName;//顾客姓名

    private List<OrderItem> orderItemList;//订单商品明细

    private Double totalPrice;//总价格

    private LocalDateTime placedAt;//下单时间

}

//订单商品类
@Data
@AllArgsConstructor
@NoArgsConstructor
class OrderItem {

    private Long productId;//商品ID

    private String productName;//商品名称

    private Double productPrice;//商品价格

    private Integer productQuantity;//商品数量

}


3、其中我们还是可以进行一些优化的,比如,mapxxx,但是其实你转化为int,就可以直接使用mapToIn的api,而且idea也会提示你,如下

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/96353.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python基础(十六):函数的初步认识

文章目录 函数的初步认识 一、函数的作用 二、函数的使用步骤 1、定义函数 2、调用函数 3、快速体验 三、函数的参数作用 四、函数的返回值作用 1、应用 五、函数的说明文档 1、语法 2、快速体验 3、函数嵌套调用 七、函数应用 1、打印图形 2、函数计算 八、总…

还在为多张Excel汇总统计发愁?Python 秒处理真香!

为什么越来越多的非程序员白领都开始学习 Python &#xff1f;他们可能并不是想要学习 Python 去爬取一些网站从而获得酷酷的成就感&#xff0c;而是工作中遇到好多数据分析处理的问题&#xff0c;用 Python 就可以简单高效地解决。本文就通过一个实际的例子来给大家展示一下 P…

新手传奇gm架设要学会的几个修改技巧

每个传奇gm对于架设一个服务器都有自己独立的看法和想法&#xff0c;一些人之所以会想着要架设一个传奇私服主要原因是自己在其他人的服力玩得不是那么舒心。所以想要按照自己的想法和思路打造一个适合自己的专属服务器进行游戏&#xff0c;其实这两者之间是有必然联系的&#…

毕业三年活得像个废物,转行网络安全,写给像我一样迷茫的人...

首先说说我吧&#xff0c;普通二本非科班商贸专业毕业&#xff0c;三年了&#xff0c;做过电商&#xff0c;做过新媒体&#xff0c;做过业务员&#xff0c;从躺平到摆烂&#xff0c;一开始还挺享受这样的生活的&#xff0c;毕竟每月4千工资&#xff0c;抛出吃住&#xff0c;剩个…

重学webpack系列(八) -- webpack的运行机制与工作原理

前面几个章节我们分别去探索了webpack的loader机制、plugin机制、devServer、sourceMap、HMR&#xff0c;但是你是否知道这些配置项是怎么去跟webpack本身执行机制挂钩的呢&#xff1f;这一章我们就来探索一下webpack的运行机制与工作原理吧。 webpack核心工作过程 我们打开w…

第十四章 文件操作

1.文件的基本操作 文件&#xff0c;对我们并不陌生&#xff0c;文件是数据源&#xff08;保存数据的地方&#xff09;的一种&#xff0c;比如大家经常使用的Word文档&#xff0c;TXT文件&#xff0c;excel文件…都是文件。文件最主要的作用就是保存数据&#xff0c;它既可以保…

用户虚拟地址空间管理-mm_struct

一、进程虚拟地址空间管理概览 二、mm_struct结构体的主要成员 atomic_t mm_users;共享同一个用户虚拟地址空间的进程的数量&#xff0c;也就是线程组包含的进程的数量atomic_t mm_count;内存描述符的引用计数struct vm_area_struct *mmap;虚拟内存区域链表struct rb_root mm_…

【java】课程设计--抽卡模拟器

文章目录工期安排自己实现菜单逻辑抽卡算法0.书写要求1.用户需求2.设计思想3.各个功能和算法描述4.系统调试中问题5.总结新知识怎么打开任务管理器改进&#xff08;进一步的设想&#xff09;交给她们实现1.注册登录2.读文件-显示查找内容暂时成功案例工期安排 1 自定义增加和删…

数据权限就该这么设计

在项目实际开发中我们不光要控制一个用户能访问哪些资源&#xff0c;还需要控制用户只能访问资源中的某部分数据。 控制一个用户能访问哪些资源我们有很成熟的权限管理模型即RBAC&#xff0c;但是控制用户只能访问某部分资源&#xff08;即我们常说的数据权限&#xff09;使用…

[附源码]Python计算机毕业设计红旗家具城管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

✿✿✿JavaScript --- 事件

目录 1.事件相关概念 2. js中注册监听&#xff08;事件绑定&#xff09;的方式 (1)在定义标签时&#xff0c;添加事件名称属性。属性值是js代码&#xff08;js代码会被自动封装到一个function函数的方法体中&#xff09; (2)通过js获取元素对象&#xff0c;再添加事件。 补…

ADI Blackfin DSP处理器-BF533的开发详解54:CVBS输出-DSP和CH7024的应用详解(含源码)

硬件准备 ADSP-EDU-BF533&#xff1a;BF533开发板 AD-HP530ICE&#xff1a;ADI DSP仿真器 软件准备 Visual DSP软件 硬件链接 CVBS OUT 视频输出 硬件实现原理 CVBS_OUT 子卡板连接在 ADSP-EDU-BF53x 开发板的扩展端口 PORT3 和 PORT4 上&#xff0c;板卡插入时&#xff0…

window10 下Tomcat安装步骤

目录先安装JDK根据JDK选择tomcat版本下载安装设置系统变量运行测试先安装JDK 略过 根据JDK选择tomcat版本 打开CMD窗口&#xff0c;运行java -version查看本机JDK版本 C:\Users\admin>java -version java version "11.0.17" 2022-10-18 LTS Java(TM) SE Runtime E…

python函数讲解进阶

关于python函数的基本知识可以点击“python函数讲解” 目录 一.函数多返回值 思考 二.函数参数种类 1.位置参数 2.关键字参数 3.缺省参数 4.不定长参数 位置传递 关键字传递 总结 三.匿名函数 函数作为参数传递 lambda匿名函数 一.函数多返回值 思考 运行之后&…

Python抓取电商平台数据 / 采集商品评论 / 可视化展示 词云图...

前言 大家早好、午好、晚好吖 ❤ ~ 我给大家准备了一些资料&#xff0c;包括: 2022最新Python视频教程、Python电子书10个G &#xff08;涵盖基础、爬虫、数据分析、web开发、机器学习、人工智能、面试题&#xff09;、Python学习路线图等等 直接在文末名片自取即可&#x…

[附源码]Node.js计算机毕业设计公交电子站牌管理系统软件Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

多模态在医疗中的应用

多模态是把要检索的模态融合起来&#xff0c;做整体的检索&#xff0c;查询和检索的必须至少有一个模态是相同的&#xff0c;也就是要查询和检索的模态都已经在融合模态里了。 跨模态是检索结果和查询的模态是不同&#xff0c;如图像检索文本&#xff0c;视频和音频。跨模态检索…

2022-12-17 TCP/IP 协议栈_2

TCP/IP 协议栈_2前言一、TCP/IP协议栈四层协议系统二、封装和分用总结前言 既然要学习计算机网络编程, 就不得不提计网祖师爷 W Richard Stevens, 天妒英才, 先生于1999年就早早陨落. 不知多少人凭着先生所著 “TCP/IP详解” 以及 “UNIX网络编程” 吃的盆满钵满. 而至今可说还…

深入浅出 - Rust 所有权与内存管理机制

一、从变量说起 fn main() {// 基本数据类型let a 5;let b a;// 指针let ptr_a &a;let ptr_b &b;println!("a value {}", a);println!("b value {}", b);println!("ptr_a value {:p}", ptr_a);println!("ptr_b value {:p}…

未来笔试重点(1)

一起成为更优秀的人 1.数组笔试重点考察 1.1整型数组与sizeof 1.2字符数组与sizeof 1.3sizeof与字符串 1.4strlen与字符串 2.指针笔试重点考察 2.1指针与sizeof 2.2指针与strlen sizeof与整型数组 int a[] { 1,2,3,4 };printf("%d\n", sizeof(a));printf(…