题⽬ 4:订单商品统计:

核⼼考点:

对象聚合(订单包含商品列表)、 MapString, ListOrder>> 、销量 / 营业额 统计、Stream ⾼阶⽤法

题⽬要求: 1. Item (商品):名称、单价、数量 → 提供⼩计⾦额⽅法; 2. Order (订单):订单号、⽤户 ID、商品列表 ListItem> → 提供订单总⾦额⽅法; 3. 按⽤户 ID分组订单(Map:⽤户→订单列表); 4. 统计:每个⽤户总消费、平台总营业额、销量最⾼的商品。

打印结果: =====⽤户消费统计===== ⽤户U002 总消费:3999.00元 ⽤户U001 总消费:7096.00元 平台总营业额:11095.00元 销量最⾼商品:⼿机,总销量:2

思路分析:

一、Item 类(商品)

复制代码
class Item {
    private String name;    // 商品名:手机、电脑
    private double price;   // 单价
    private int count;      // 购买数量

    // 小计金额 = 单价 × 数量(题目要求必须提供的方法)
    public double getSubtotal() {
        return price * count;
    }

    // 构造方法:创建商品时传入 名称、单价、数量
    public Item(String name, double price, int count) {
        this.name = name;
        this.price = price;
        this.count = count;
    }

    // getter:外部要读取商品信息必须用get
    public String getName() { return name; }
    public int getCount() { return count; }
}

核心思路

  • Item 是基础数据单元,只负责自己的单价、数量、小计。
  • getSubtotal() 是题目强制要求:单个商品的总价
  • 提供 getter,让外部类(Order)能读取商品名称、数量。

二、Order 类(订单)

复制代码
class Order {
    private String orderId;     // 订单编号 O001
    private String userId;      // 用户编号 U001
    private List<Item> itemList; // 一个订单包含多个商品 → 对象聚合!

    // 订单总金额 = 所有商品的小计加起来(题目要求)
    public double getTotalAmount() {
        return itemList.stream()
                .mapToDouble(Item::getSubtotal) // 把每个商品转成小计金额
                .sum(); // 求和
    }

    // 构造方法:创建订单时传入 订单号、用户ID、商品列表
    public Order(String orderId, String userId, List<Item> itemList) {
        this.orderId = orderId;
        this.userId = userId;
        this.itemList = itemList;
    }

    // getter
    public String getUserId() { return userId; }
    public List<Item> getItemList() { return itemList; }
}

核心思路

  1. 对象聚合(核心考点)

    • 一个订单 包含 多个商品
    • 代码体现:List<Item> itemList
  2. getTotalAmount() 订单总金额

    • 流处理商品列表
    • mapToDouble(Item::getSubtotal):把每个商品 → 金额
    • sum():把所有金额加起来 = 订单总价

三、主程序:完整执行流程(最关键)

第 1 步:构造测试数据

复制代码
// 商品
Item phone = new Item("手机", 1999, 1);
Item phone2 = new Item("手机", 1999, 1);
Item computer = new Item("电脑", 5099, 1);
Item earphone = new Item("耳机", 1999, 1);

// 订单
Order o1 = new Order("O001", "U001", Arrays.asList(phone, computer));
Order o2 = new Order("O002", "U001", Arrays.asList(earphone));
Order o3 = new Order("O003", "U002", Arrays.asList(phone2));

// 所有订单放到一个集合里
List<Order> orderList = Arrays.asList(o1, o2, o3);

思路

  • 先造商品
  • 再造订单,订单里装入商品
  • 最后把所有订单放到 orderList,方便统一处理

第 2 步:按用户 ID 分组订单(Map<String, List<Order>>)

复制代码
Map<String, List<Order>> userOrderMap = orderList.stream()
        .collect(Collectors.groupingBy(Order::getUserId));

思路(Stream 分组核心)

  • groupingBy(Order::getUserId)
    • 按照 userId 分组
    • key = 用户 ID
    • value = 这个用户的所有订单列表

第 3 步:统计每个用户总消费

复制代码
userOrderMap.forEach((userId, orders) -> {
    double total = orders.stream()
            .mapToDouble(Order::getTotalAmount) // 每个订单 → 金额
            .sum(); // 求和 = 该用户总消费
    System.out.printf("用户%s 总消费:%.2f元%n", userId, total);
});

思路

  • 遍历每个用户
  • 把该用户的所有订单金额加起来
  • 输出格式化结果

第 4 步:统计平台总营业额

复制代码
double platformTotal = orderList.stream()
        .mapToDouble(Order::getTotalAmount)
        .sum();
System.out.printf("平台总营业额:%.2f元%n", platformTotal);

思路

  • 所有订单的金额加起来
  • 就是平台总营业额
  • 最简单的统计

第 5 步:统计销量最高的商品(最难!Stream 高阶)

第一步:把所有订单里的商品全部展开

复制代码
orderList.stream()
    .flatMap(order -> order.getItemList().stream())

思路

  • flatMap = 扁平化
  • 把:订单1[商品1,商品2]、订单2[商品3]变成:[商品1,商品2,商品3]

第二步:按商品名统计总销量

复制代码
.collect(Collectors.groupingBy(
        Item::getName,         // 按商品名分组
        Collectors.summingInt(Item::getCount) // 每组数量求和
));

得到一个 Map:

  • 手机 → 2
  • 电脑 → 1
  • 耳机 → 1

第三步:找出销量最大的那个

复制代码
Map.Entry<String, Integer> topItem = itemSalesMap.entrySet().stream()
        .max(Map.Entry.comparingByValue()) // 按销量值比较,取最大
        .orElse(null);

思路

  • 比较 Map 里的 value(销量)
  • 取出最大的那一组
  • 最后打印商品名 + 销量
相关推荐
invicinble6 小时前
springboot提供的机制大全
java·spring boot·后端
彦为君6 小时前
JavaSE-11-ByteBuffer(NIO核心组件)
java·开发语言·前端·数据库·后端·spring·nio
Kiling_07046 小时前
面向对象和集合编程题 ( 二 )
java·开发语言·数据结构·算法
菜鸡儿齐6 小时前
Future接口学习
java·服务器·开发语言
过期动态6 小时前
【LeetCode 热题 100】两数之和— 暴力法与哈希表法详解
java·数据结构·算法·leetcode·散列表
Refrain_zc6 小时前
Android开发在线音频播放器之章节三核心PlayerService
java
日月云棠6 小时前
17 Dubbo 2.7 集群容错策略源码解析
java·后端
Refrain_zc6 小时前
Android开发纯按键文件浏览器
java