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

如何读取CSV文件并存入HashMap<String, LatLon>?遇异常求解

问题分析与解决思路

你的代码抛出InputMismatchException及无法正确存储数据的原因主要有以下几点:

核心问题

  1. 字段读取顺序完全错误
    CSV格式是Location#, Latitude, Longitude,但你的代码先尝试读取纬度/经度(double类型),最后读取Location#(字符串)。当Scanner遇到第一个字段(字符串类型的位置编号或表头)时,用nextDouble()读取必然会抛出类型不匹配异常。

  2. 分隔符设置不严谨
    仅设置逗号为分隔符会忽略换行符的存在,导致Scanner跨行读取内容,同时无法处理CSV中常见的“逗号+空格”格式(比如Loc1, 39.9, 116.3)。

  3. LatLon对象重复引用
    你只创建了一个LatLon对象,循环中仅修改其lat/lon值,最终HashMap中所有键都会指向同一个对象,所有条目都会覆盖为最后一次的坐标值。

  4. 未处理表头(若存在)
    如果CSV第一行是表头(如Location#,Latitude,Longitude),直接读取会导致字符串被当作double解析,触发异常。

修正后的代码

推荐采用按行读取+拆分字段的方式,这种方式更稳定,也更容易处理CSV的格式细节:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Scanner;

public class LocationReader {
    public static void main(String[] args) {
        String path = "fileName.csv";
        HashMap<String, LatLon> maps = new HashMap<>();

        try (Scanner s = new Scanner(new File(path))) {
            // 跳过表头(如果CSV有表头的话,没有则删除这行)
            if (s.hasNextLine()) {
                s.nextLine();
            }

            while (s.hasNextLine()) {
                String line = s.nextLine().trim();
                // 拆分字段:匹配逗号及后面可能的空格
                String[] fields = line.split(",\\s*");

                // 确保每行有3个有效字段
                if (fields.length == 3) {
                    String locationId = fields[0];
                    double lat = Double.parseDouble(fields[1]);
                    double lon = Double.parseDouble(fields[2]);
                    // 每次循环创建新的LatLon对象,避免引用重复
                    maps.put(locationId, new LatLon(lat, lon));
                }
            }
        } catch (FileNotFoundException e) {
            System.err.println("文件未找到:" + path);
            e.printStackTrace();
        } catch (NumberFormatException e) {
            System.err.println("坐标格式错误,请检查CSV内容");
            e.printStackTrace();
        }
    }

    // 假设你的LatLon类是这样的
    static class LatLon {
        private double latitude;
        private double longitude;

        public LatLon(double latitude, double longitude) {
            this.latitude = latitude;
            this.longitude = longitude;
        }

        // 可选:添加getter方法
        public double getLatitude() {
            return latitude;
        }

        public double getLongitude() {
            return longitude;
        }
    }
}

额外优化建议

  • 使用try-with-resources语法(如上代码),无需手动关闭Scanner,确保资源自动释放。
  • 添加字段长度校验和异常捕获,避免因CSV格式错误导致程序崩溃。
  • 如果CSV内容包含带逗号的字符串(比如"New York, NY",40.7,-74.0),手动拆分的方式会失效,此时建议使用成熟的CSV解析库(如OpenCSV)来处理复杂场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 17:16:00