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

高校餐厅队列建模:Java优先级队列代码报错求助

解决Java PriorityQueue的ClassCastException问题

嘿,我来帮你搞定这个卡了好几天的问题!先直接说错误根源:你遇到的ClassCastException是因为你用了AbstractMap.SimpleEntry作为PriorityQueue的元素,但既没有给队列指定自定义比较器,这个Entry的默认排序逻辑也不符合你的需求,而且你明明已经写好了Customer类和CustomerComparator,却完全没用到它们——这才是核心问题!

问题拆解

  1. PriorityQueue排序逻辑缺失:你定义的Queue<Map.Entry<Integer, Integer>> Restaurant = new PriorityQueue<>();没有传入比较器,队列会尝试把元素强制转成Comparable做自然排序,但AbstractMap.SimpleEntry的compareTo是先比key再比value的升序逻辑,和你需要的「年级优先级(Seniors>Juniors>sophomores>freshmen)」完全不符。
  2. 自定义Customer类未被使用:你已经封装了Customer类来保存grade和到店时间,但代码里却用Map.Entry存数据,完全浪费了这个类的设计。
  3. grade生成逻辑有bug:你生成grade时误用了判断到客的rand变量,而不是专门生成年级的rand2,导致grade的生成完全错误。
  4. 静态waitingTime的风险:把waitingTime定义为静态变量,会导致多次调用方法或多线程场景下的状态混乱,应该改成局部变量。

修复后的完整代码

import java.util.*;

// 修正比较器逻辑:grade越小优先级越高(1=Seniors优先级最高)
class CustomerComparator implements Comparator<Customer> {
    @Override
    public int compare(Customer c1, Customer c2) {
        // 直接用Integer的compare方法,逻辑更简洁
        return Integer.compare(c1.getGrade(), c2.getGrade());
    }
}

class Customer {
    private int grade;
    private int arrivalTime; // 重命名为arrivalTime更贴合语义,记录顾客到店的分钟数

    public Customer(int grade, int arrivalTime) {
        this.grade = grade;
        this.arrivalTime = arrivalTime;
    }

    public int getGrade() {
        return grade;
    }

    public int getArrivalTime() {
        return arrivalTime;
    }

    // 重写toString,方便调试时打印队列内容
    @Override
    public String toString() {
        return String.format("(Grade:%d, Arrival:%d)", grade, arrivalTime);
    }
}

public class RestaurantPriority {
    // 改为Customer类型的PriorityQueue,并传入自定义比较器
    private static Queue<Customer> restaurantQueue = new PriorityQueue<>(new CustomerComparator());

    public static void main(String[] args) {
        simulateRestaurant();
    }

    public static void simulateRestaurant() {
        int currentTime = 360; // 从早6点(第360分钟)开始
        int orderProcessingTime = 0; // 改为局部变量,记录当前订单剩余处理时间

        // 模拟营业时间:早6点到晚12点(第1440分钟)
        while (currentTime < 1440) {
            // 1. 处理当前订单的时间递减
            if (orderProcessingTime > 0) {
                orderProcessingTime--;
                // 订单处理完成,取出队列下一位顾客并生成新的处理时间
                if (orderProcessingTime == 0 && !restaurantQueue.isEmpty()) {
                    restaurantQueue.poll();
                    orderProcessingTime = 2 + (int) (Math.random() * 6); // 生成2-7分钟的随机数
                }
            } else if (!restaurantQueue.isEmpty()) {
                // 无正在处理的订单,但队列有顾客,开始处理第一位
                orderProcessingTime = 2 + (int) (Math.random() * 6);
            }

            // 2. 判断是否有新顾客到店(每分钟20%概率)
            double arrivalChance = Math.random();
            if (arrivalChance < 0.2) {
                // 生成顾客年级:四个年级各25%概率
                double gradeChance = Math.random();
                int grade;
                if (gradeChance < 0.25) {
                    grade = 1; // Seniors
                } else if (gradeChance < 0.5) {
                    grade = 2; // Juniors
                } else if (gradeChance < 0.75) {
                    grade = 3; // sophomores
                } else {
                    grade = 4; // freshmen
                }
                restaurantQueue.add(new Customer(grade, currentTime));
            }

            // 3. 打印当前状态
            System.out.printf("Time:%d, Remaining Process Time:%d, Queue:%s%n",
                    currentTime, orderProcessingTime, restaurantQueue);

            currentTime++;
        }

        // 处理营业结束后剩余的顾客
        System.out.println("=== 营业时间结束,处理剩余顾客 ===");
        while (!restaurantQueue.isEmpty()) {
            if (orderProcessingTime == 0) {
                restaurantQueue.poll();
                orderProcessingTime = 2 + (int) (Math.random() * 6);
            }
            orderProcessingTime--;
            System.out.printf("Time:%d, Remaining Process Time:%d, Queue:%s%n",
                    currentTime, orderProcessingTime, restaurantQueue);
            currentTime++;
        }
    }
}

关键修改点说明

  • PriorityQueue类型修正:将队列改为Queue<Customer>并传入CustomerComparator,确保队列按照年级优先级排序(grade越小优先级越高)。
  • Customer类优化:重命名变量并添加toString方法,让代码语义更清晰,调试更方便。
  • 修复grade生成bug:改用专门的gradeChance变量生成年级,逻辑正确。
  • waitingTime改为局部变量:避免静态变量的状态污染,逻辑更严谨。
  • 简化循环逻辑:将for循环改为while循环,处理营业结束后的剩余顾客更合理,避免原代码中i自增导致的循环异常。

现在运行这段代码,应该不会再出现ClassCastException,而且完全符合你的需求逻辑啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 15:08:13