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

求助:ArrayList<Book>按numPoints()排序失败,两段实现均有问题

排查两段Book列表排序代码的问题

我来帮你逐个分析这两段代码的问题所在,以及对应的修复方案:

第一段选择排序代码的问题:无法正确排序

这段代码的核心问题有两个:

  • indMax变量未更新:在内部循环找到更大numPoints()的Book时,你只更新了临时变量mon,但没有同步更新indMax(记录最大值元素的索引)。这导致后续的交换判断if(indMax != i)永远不成立,根本没有执行元素交换操作,自然无法完成排序。
  • 打印循环变量错误:最后打印列表的循环中,你用了未定义的变量j(循环变量是s),这会导致编译错误或运行异常。

修复后的第一段代码:

public static void sort() {
    Book mon = null;
    int indMax = 0;
    for(int i=0; i<b.size()-1; i++){
        mon = b.get(i);
        indMax = i;
        for(int j=i+1; j<b.size(); j++){
            if(b.get(j).numPoints() > mon.numPoints()){
                mon = b.get(j);
                indMax = j; // 关键:更新最大值的索引
            }
        }
        if(indMax != i){
            // 交换当前i位置和最大值位置的元素
            b.set(indMax, b.get(i));
            b.set(i, mon);
        }
    }
    // 修正打印的循环变量
    for(int s=0; s<b.size(); s++) {
        b.get(s).show();
    }
}

第二段代码的问题:IndexOutOfBoundsException异常

这段代码抛出数组越界异常的原因是**vMax和iMax没有在每次循环中重置**:
第一次循环时,你找到了列表中的最大值,vMax被设为该最大值,iMax是对应的索引。但当你把这个元素从b中移除后,下一次循环时vMax仍然保留着上一次的最大值,而当前b中的所有元素的numPoints()都小于这个值,导致iMax始终不会被更新,仍然是上一次的索引。如果此时b的长度已经小于该索引,就会触发IndexOutOfBoundsException(比如你遇到的Index: 2, Size: 2,说明第二次循环时iMax还是2,但当前b的长度已经是2,索引只能到1)。

修复后的第二段代码:

public static void sort() {
    ArrayList<Book> o = new ArrayList<Book>();
    while(b.size()!=0) {
        // 每次循环前重置最大值和对应的索引,初始化为当前列表第一个元素
        double vMax = b.get(0).numPoints();
        int iMax = 0;
        for(int i = 0; i<b.size(); i++) {
            if(vMax < b.get(i).numPoints()) {
                vMax = b.get(i).numPoints();
                iMax = i;
            }
        }
        o.add(b.get(iMax));
        b.remove(iMax);
    }
    for(int j=0; j<o.size(); j++) {
        o.get(j).show();
    }
}

额外建议:使用Java内置排序简化代码

其实Java已经提供了非常成熟的排序API,不需要自己手动实现排序算法,这样代码更简洁也更不易出错。比如可以用Comparator按numPoints()降序排序:

public static void sort() {
    // 按numPoints()从大到小排序
    b.sort((book1, book2) -> Double.compare(book2.numPoints(), book1.numPoints()));
    // 增强for循环打印,更简洁
    for(Book book : b) {
        book.show();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:35:03