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

Java读取中间文本文件实现分组列数据求和及百分比计算的问题求助

Solution for Grouped Sum and Percentage Calculation in Java

I've run into this exact issue before with fixed-width formatted files converted to space-separated lines—those variable spaces are a real pain! Let's fix this step by step, starting with the parsing problem and then building out the grouped sum and percentage calculation.

Here's a complete, working solution that addresses your whitespace parsing issue, handles state-wise grouping, and computes the required percentages:

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

// Custom class to hold aggregated data for each state
class StateAggregate {
    int totalPopulation;
    int schoolAgeChildren;
    int povertyChildren;

    public StateAggregate() {
        this.totalPopulation = 0;
        this.schoolAgeChildren = 0;
        this.povertyChildren = 0;
    }

    public void add(int total, int schoolAge, int poverty) {
        this.totalPopulation += total;
        this.schoolAgeChildren += schoolAge;
        this.povertyChildren += poverty;
    }
}

public class StatePopulationAnalyzer {
    public static void main(String[] args) {
        // Map to hold aggregated data per state code
        Map<String, StateAggregate> stateDataMap = new HashMap<>();

        try (BufferedReader reader = new BufferedReader(new FileReader("IntermediateSmallAreaIncomePovertyEstData.txt"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                // Use Scanner to handle variable whitespace automatically
                Scanner lineScanner = new Scanner(line);
                String stateCode = lineScanner.next();
                int totalPop = lineScanner.nextInt();
                int schoolAge = lineScanner.nextInt();
                int poverty = lineScanner.nextInt();

                // Get or create the aggregate entry for this state
                StateAggregate aggregate = stateDataMap.getOrDefault(stateCode, new StateAggregate());
                aggregate.add(totalPop, schoolAge, poverty);
                stateDataMap.put(stateCode, aggregate);
            }

            // Print formatted results
            System.out.printf("%-10s %-15s %-20s %-25s %-20s\n", 
                    "State Code", "Total Population", "School Age Children", "Poverty Children", "% Poverty (School Age)");
            System.out.println("--------------------------------------------------------------------------------------------------------");
            for (Map.Entry<String, StateAggregate> entry : stateDataMap.entrySet()) {
                String stateCode = entry.getKey();
                StateAggregate data = entry.getValue();
                // Calculate percentage, handle division by zero edge case
                double povertyPercentage = data.schoolAgeChildren == 0 ? 0.0 
                        : (double) data.povertyChildren / data.schoolAgeChildren * 100;

                System.out.printf("%-10s %-15d %-20d %-25d %-20.2f%%\n", 
                        stateCode, data.totalPopulation, data.schoolAgeChildren, data.povertyChildren, povertyPercentage);
            }

        } catch (IOException e) {
            System.err.println("Error reading file: " + e.getMessage());
        } catch (NumberFormatException e) {
            System.err.println("Error parsing numeric data: " + e.getMessage());
        }
    }
}

Key Fixes & Improvements:

  1. Variable Whitespace Handling

    • Instead of split(" "), we use Scanner which automatically splits on any whitespace (spaces, tabs, etc.)—this eliminates empty array elements from multiple spaces entirely.
    • If you prefer using split, replace the Scanner logic with:
      String[] parts = line.trim().split("\\s+"); // \\s+ matches one or more whitespace characters
      String stateCode = parts[0];
      int totalPop = Integer.parseInt(parts[1]);
      int schoolAge = Integer.parseInt(parts[2]);
      int poverty = Integer.parseInt(parts[3]);
      
    • trim() removes leading/trailing whitespace to avoid unexpected empty elements at the start of the array.
  2. State-Wise Grouped Aggregation

    • A HashMap<String, StateAggregate> stores summed values per state code. The StateAggregate class keeps track of the three totals in an organized, reusable way.
    • getOrDefault() simplifies checking for existing state entries—if no entry exists, we create a new StateAggregate instance.
  3. Percentage Calculation

    • We cast values to double before division to avoid integer division (which would truncate results to 0 if poverty counts are smaller than school age counts).
    • Added a check for division by zero (in case a state has no school age children) to prevent runtime errors.
  4. Robust Resource Management

    • Try-with-resources (try (BufferedReader reader = ...)) ensures the file reader is automatically closed, even if an exception occurs.
  5. Clean Formatted Output

    • printf aligns columns neatly, making the final results easy to read and interpret.

Why Your Original Test.java Failed:

  • It summed all rows into a single totalPop variable instead of grouping by state code.
  • split(" ") creates empty strings in the array when multiple spaces are present, so population[1] wouldn't always point to the total population value (leading to parsing errors).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 18:07:31