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

我的Comparable接口逻辑存在问题?优先级队列排序结果不符预期

解决PriorityQueue转List时的顺序异常问题

你碰到的问题其实是Java PriorityQueue 的一个常见坑——直接通过队列构造 ArrayList 并不会得到按优先级排序的元素。这是因为PriorityQueue内部是用堆结构实现的,它的迭代器不会按照优先级顺序遍历元素,只有调用poll()方法时才会取出当前优先级最高的元素。

问题根源

你原代码里的这一行是导致输出顺序错误的关键:

List<Students> studentList = new ArrayList<Students>(pq);

当用队列作为参数构造ArrayList时,会直接迭代队列中的元素,但堆的迭代顺序和优先级顺序完全不一致,所以最终List里的元素顺序就乱了。

修复方案

把构造List的逻辑改成循环调用poll(),直到队列清空:

List<Students> studentList = new ArrayList<Students>();
while(!pq.isEmpty()) {
    studentList.add(pq.poll());
}

每次调用poll()都会移除并返回队列中优先级最高的元素,这样循环下来,List里的元素就严格按照你定义的优先级规则排序了。

优化后的完整代码

顺便给你的compareTo方法做了点简化,同时补充了equals和hashCode方法(符合Comparable接口的规范,避免潜在问题):

import java.util.*;

class Priorities{
    public List<Students> getStudents(List<String> events) {
        PriorityQueue<Students> pq = new PriorityQueue<>();
        for (String s : events) {
            if (s.startsWith("ENTER")) {
                String[] arr = s.split(" ");
                int id = Integer.parseInt(arr[3]);
                String name = arr[1];
                double cgpa = Double.parseDouble(arr[2]);
                pq.add(new Students(id, name, cgpa));
            } else {
                pq.poll();
            }
        }
        // 正确的顺序获取方式
        List<Students> studentList = new ArrayList<>();
        while (!pq.isEmpty()) {
            studentList.add(pq.poll());
        }
        return studentList;
    }
}

class Students implements Comparable<Students>{
    int id;
    String name;
    double cgpa;

    public Students(int id, String name, double cgpa) {
        this.id = id;
        this.name = name;
        this.cgpa = cgpa;
    }

    // Getter和Setter方法保持不变
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public double getCgpa() { return cgpa; }
    public void setCgpa(double cgpa) { this.cgpa = cgpa; }

    @Override
    public int compareTo(Students other) {
        // 先比较CGPA,高的优先
        int cgpaCompare = Double.compare(other.cgpa, this.cgpa);
        if (cgpaCompare != 0) {
            return cgpaCompare;
        }
        // CGPA相同则按名称升序(区分大小写)
        int nameCompare = this.name.compareTo(other.name);
        if (nameCompare != 0) {
            return nameCompare;
        }
        // 名称也相同则按id升序
        return Integer.compare(this.id, other.id);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Students students = (Students) o;
        return id == students.id && Double.compare(students.cgpa, cgpa) == 0 && name.equals(students.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, cgpa);
    }
}

验证结果

用你提供的示例输入运行修正后的代码,输出会和预期完全一致:

Dan
Ashley
Shafaet
Maria

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 07:48:12