You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取系统中消费最高的10位Taxpayer?(非Java 8实现)

问题:获取消费总额最高的10位Taxpayer(非Java 8实现)

背景与需求

咱们先梳理下当前场景:

  • 现有类结构:User 基类,Taxpayer 继承自 User,还有记录消费明细的 Expense 类
  • Main 类维护两个核心集合:Map<String, User> users(存储系统所有用户)和 Map<String, Expense> expenses(存储所有消费记录)
  • 核心需求:找出系统内消费总额最高的10位Taxpayer,需要先判断用户是否为Taxpayer身份,再计算其所有消费的金额总和
  • 现存问题:当前代码完全没处理「列表已满10个时,替换掉消费额更低的末尾用户」的逻辑,而且要求必须用非Java 8的实现方式

现有问题代码

public List<Taxpayer> getTenTaxpayers(){ 
    List<Taxpayer> list = new ArrayList<Taxpayer>(); 
    for(User u: this.users.values()){ 
        if(!u.getUserType()){ // 原代码逻辑:getUserType返回false代表是Taxpayer
            Taxpayer t = (Taxpayer) u; 
            double sum = 0; 
            for(Expense e: this.expenses.values()){ 
                if(t.getNIF().equals(e.getNIFClient())){ // 通过NIF匹配Taxpayer和其消费记录
                    sum += e.getValue(); 
                    if(list.size()<10){ 
                        list.add(t.clone()); 
                    } 
                } 
            } 
        } 
    } 
    return list; // 原代码遗漏return,这里补上
}

问题分析

这段代码有两个核心硬伤:

  1. 效率极低:每遍历一个Taxpayer,就要全量扫描所有Expense记录,重复计算量极大,时间复杂度是O(M*N)(M为用户数,N为消费记录数)
  2. 逻辑缺失:只处理了列表未满10个的场景,完全没考虑当列表已满时,如何替换掉消费额更低的末尾元素,也没有对列表按消费总额排序

非Java 8解决方案

我们分两步优化:先预处理消费总额减少重复计算,再维护一个有序的Top10列表

步骤1:预处理消费总额

先遍历所有Expense,按客户NIF统计总消费金额,存在一个Map中。后续每个Taxpayer直接从Map中取对应总额即可,不用反复扫描Expense集合。

步骤2:维护有序的Top10列表

保持列表始终按消费总额降序排列:

  • 当列表未满10个时,直接加入新的Taxpayer并重新排序
  • 当列表已满10个时,比较当前Taxpayer的总额与列表最后一位的总额,如果更高,就替换末尾元素并重新排序

修正后的代码

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public List<Taxpayer> getTenTaxpayers() {
    // 第一步:预处理所有消费记录,按NIF统计总消费金额
    Map<String, Double> nifExpenseSumMap = new HashMap<String, Double>();
    for (Expense e : this.expenses.values()) {
        String clientNif = e.getNIFClient();
        // 累加当前NIF的消费总额,没有记录则默认0
        double currentTotal = nifExpenseSumMap.getOrDefault(clientNif, 0.0);
        nifExpenseSumMap.put(clientNif, currentTotal + e.getValue());
    }

    // 第二步:维护消费总额最高的10位Taxpayer列表
    List<Taxpayer> top10Taxpayers = new ArrayList<Taxpayer>();
    for (User u : this.users.values()) {
        // 按原代码逻辑判断是否为Taxpayer
        if (!u.getUserType()) {
            Taxpayer taxpayer = (Taxpayer) u;
            String nif = taxpayer.getNIF();
            // 获取该Taxpayer的总消费,无消费则为0
            double totalExpense = nifExpenseSumMap.getOrDefault(nif, 0.0);

            if (top10Taxpayers.size() < 10) {
                // 列表未满10个,直接加入克隆后的对象(避免修改原数据)
                top10Taxpayers.add(taxpayer.clone());
                // 排序:按消费总额降序排列
                Collections.sort(top10Taxpayers, new Comparator<Taxpayer>() {
                    @Override
                    public int compare(Taxpayer t1, Taxpayer t2) {
                        double sum1 = nifExpenseSumMap.getOrDefault(t1.getNIF(), 0.0);
                        double sum2 = nifExpenseSumMap.getOrDefault(t2.getNIF(), 0.0);
                        // 降序排列,用Double.compare避免精度问题
                        return Double.compare(sum2, sum1);
                    }
                });
            } else {
                // 列表已满,取当前列表末尾(消费最低)的Taxpayer总额
                Taxpayer lowestTopTaxpayer = top10Taxpayers.get(top10Taxpayers.size() - 1);
                double lowestTotal = nifExpenseSumMap.getOrDefault(lowestTopTaxpayer.getNIF(), 0.0);

                // 如果当前Taxpayer消费更高,替换末尾元素并重新排序
                if (totalExpense > lowestTotal) {
                    top10Taxpayers.remove(top10Taxpayers.size() - 1);
                    top10Taxpayers.add(taxpayer.clone());
                    Collections.sort(top10Taxpayers, new Comparator<Taxpayer>() {
                        @Override
                        public int compare(Taxpayer t1, Taxpayer t2) {
                            double sum1 = nifExpenseSumMap.getOrDefault(t1.getNIF(), 0.0);
                            double sum2 = nifExpenseSumMap.getOrDefault(t2.getNIF(), 0.0);
                            return Double.compare(sum2, sum1);
                        }
                    });
                }
            }
        }
    }

    return top10Taxpayers;
}

关键优化点说明

  • 效率提升:时间复杂度从O(M*N)降到O(M+N),大幅减少重复计算
  • 逻辑完善:实现了「满10个时替换低消费用户」的核心逻辑,且始终保持列表有序
  • 非Java 8兼容:完全使用Java 7及之前的API,没有用到Stream、Lambda等Java 8特性
  • 数据安全:保留原代码的t.clone()操作,避免修改原User对象的引用

内容的提问来源于stack exchange,提问作者John Mulaney

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:02:00