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

如何从文本文件读取数据存入PriorityQueue并输出Top5最大值条目

问题分析

你的代码存在两个核心问题:

  • 默认的PriorityQueue<String>是按字符串字典序排序,而非每行末尾的数值大小排序,导致输出结果完全不符合预期。
  • 直接将整行字符串存入队列,无法基于数值字段定制排序逻辑。
解决方案

我们需要让PriorityQueue按照每行的数值字段降序排序,若仅需最大的5条数据,用小顶堆维护固定大小队列会更高效(避免存储所有数据)。以下提供三种实现方式:

方式一:字符串拆分+自定义Comparator

直接拆分每行提取数值,定制排序规则:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Comparator;
import java.util.PriorityQueue;

public class Top5Data {
    public static void main(String[] args) {
        // 按数值降序排序的PriorityQueue
        PriorityQueue<String> queue = new PriorityQueue<>((line1, line2) -> {
            int num1 = Integer.parseInt(line1.split("\\s+")[2]);
            int num2 = Integer.parseInt(line2.split("\\s+")[2]);
            // 降序:大的元素排在前面
            return Integer.compare(num2, num1);
        });

        String file = "data.txt";
        String line;
        // try-with-resources自动关闭流
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            while ((line = br.readLine()) != null) {
                queue.offer(line);
            }
        } catch (IOException e) {
            System.err.println("读取文件失败:" + e.getMessage());
        }

        // 输出前5条最大记录
        System.out.println("数值最大的5条数据:");
        int count = 0;
        while (!queue.isEmpty() && count < 5) {
            count++;
            System.out.println(count + ". " + queue.poll());
        }
    }
}

方式二:小顶堆优化内存(推荐)

数据量较大时,仅维护大小为5的小顶堆,堆顶是当前最小元素,最终堆内即为最大的5个元素:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Comparator;
import java.util.PriorityQueue;

public class Top5DataOptimize {
    public static void main(String[] args) {
        // 小顶堆:堆顶为当前最小元素,队列最多存5个元素
        PriorityQueue<String> minHeap = new PriorityQueue<>((line1, line2) -> {
            int num1 = Integer.parseInt(line1.split("\\s+")[2]);
            int num2 = Integer.parseInt(line2.split("\\s+")[2]);
            // 升序排序,堆顶是最小元素
            return Integer.compare(num1, num2);
        });

        String file = "data.txt";
        String line;
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            while ((line = br.readLine()) != null) {
                minHeap.offer(line);
                // 超过5个元素时,移除当前最小的堆顶元素
                if (minHeap.size() > 5) {
                    minHeap.poll();
                }
            }
        } catch (IOException e) {
            System.err.println("读取文件失败:" + e.getMessage());
        }

        // 小顶堆取出的是从小到大,倒序输出得到从大到小的结果
        System.out.println("数值最大的5条数据:");
        String[] top5 = new String[5];
        int index = 4;
        while (!minHeap.isEmpty()) {
            top5[index--] = minHeap.poll();
        }
        for (int i = 0; i < top5.length; i++) {
            System.out.println((i+1) + ". " + top5[i]);
        }
    }
}

方式三:实体类封装(可读性更强)

业务逻辑复杂时,封装为实体类更清晰:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Comparator;
import java.util.PriorityQueue;

// 封装每行数据的实体类
class DataRecord {
    private String name;
    private String date;
    private int value;

    public DataRecord(String name, String date, int value) {
        this.name = name;
        this.date = date;
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    @Override
    public String toString() {
        return name + " " + date + " " + value;
    }
}

public class Top5DataWithClass {
    public static void main(String[] args) {
        // 按数值降序排序的队列
        PriorityQueue<DataRecord> queue = new PriorityQueue<>(
            Comparator.comparingInt(DataRecord::getValue).reversed()
        );

        String file = "data.txt";
        String line;
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            while ((line = br.readLine()) != null) {
                String[] parts = line.split("\\s+");
                DataRecord record = new DataRecord(parts[0], parts[1], Integer.parseInt(parts[2]));
                queue.offer(record);
            }
        } catch (IOException e) {
            System.err.println("读取文件失败:" + e.getMessage());
        }

        System.out.println("数值最大的5条数据:");
        int count = 0;
        while (!queue.isEmpty() && count < 5) {
            count++;
            System.out.println(count + ". " + queue.poll());
        }
    }
}
预期输出

运行任意一种方式,都会得到正确的Top5结果:

1. WHguJUYeLBYoton 1987-11-24 9664
2. uecbYlaCeaTSAsr 1937-4-1 9305
3. amHPTQXCqHkYtXW 1991-8-24 8778
4. dMGDWfIrPctuwBs 2005-3-15 8567
5. ZsvJcYbmOFmdXfG 1923-10-10 8314

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 00:45:43