读取坐标文件时,如何用PointID字符串命名Punto对象?
问题与解决方案:动态关联PointID与Punto对象
问题描述
我需要读取一个包含PointID CoordX CoordY结构的文件,示例内容如下:
1 565.0 575.0 2 25.0 185.0 3 345.0 750.0 4 945.0 685.0 5 845.0 655.0
其中PointID是对应点的ID,我想实现类似以下代码的效果,让每个PointID对应一个Punto对象:
Punto p1 = new Punto(16.47, 36.10); Punto p2 = new Punto(16.47, 280.44); Punto p3 = new Punto(115.09, 92.54); Punto p4 = new Punto(364.39, 197.37);
但我编写的代码在创建对象时遇到了问题——无法用字符串numPunto作为对象名称,核心错误代码如下:
Punto (Object)numPunto = new Punto (Double.parseDouble(cordX), Double.parseDouble(cordY));
完整的错误代码片段:
public ArrayList<Punto> puntosFichero(File fich) throws Exception { String numPunto = ""; String cordX = ""; String cordY = ""; String tmp = ""; ArrayList<Punto> mapa = new ArrayList(); //Opens the file try { scannerLectura = new Scanner(fich); } catch (Exception e) { throw new Exception("Error: Abrir fichero"); } //Reads the file and sets the ArrayList while(scannerLectura.hasNext()){ tmp = scannerLectura.next(); if (tmp.contentEquals("NODE_COORD_SECTION")){ while(!tmp.contentEquals("EOF")){ numPunto = scannerLectura.next(); //P(numPunto) cordX = scannerLectura.next(); //CordX cordY = scannerLectura.next(); //CordY System.out.println("Punto " + numPunto + ": [" + cordX + " , " + cordY + "]"); Punto (Object)numPunto = new Punto (Double.parseDouble(cordX), Double.parseDouble(cordY)); mapa.add(Integer.parseInt(numPunto)); } } } //Closes the file scannerLectura.close(); return mapa; }
核心问题
Java不支持动态命名变量/对象,你不能用字符串值直接作为对象的名称。你真正需要的是把Punto对象和对应的PointID关联起来,而非创建对应名称的变量。
正确实现方式
用Map<Integer, Punto>存储ID与Punto对象的映射关系,既能通过ID快速查找对应对象,也完全符合Java语法规范。同时修正原代码中的循环逻辑、元素存储等错误,最终代码如下:
import java.io.File; import java.util.HashMap; import java.util.Map; import java.util.Scanner; // 假设Punto类已定义,包含对应构造方法 class Punto { private double x; private double y; public Punto(double x, double y) { this.x = x; this.y = y; } // 可选:添加toString方便调试 @Override public String toString() { return "Punto{" + "x=" + x + ", y=" + y + '}'; } } public class PuntoFileReader { public Map<Integer, Punto> puntosFichero(File fich) throws Exception { Map<Integer, Punto> puntoMap = new HashMap<>(); Scanner scannerLectura = null; try { scannerLectura = new Scanner(fich); // 定位到NODE_COORD_SECTION段 while (scannerLectura.hasNext()) { String tmp = scannerLectura.next(); if (tmp.equals("NODE_COORD_SECTION")) { // 读取节点数据直到遇到EOF while (scannerLectura.hasNext()) { String token = scannerLectura.next(); if (token.equals("EOF")) { break; } // 解析ID和坐标 int pointId = Integer.parseInt(token); double coordX = Double.parseDouble(scannerLectura.next()); double coordY = Double.parseDouble(scannerLectura.next()); // 创建Punto对象并关联ID Punto punto = new Punto(coordX, coordY); puntoMap.put(pointId, punto); System.out.println("Punto " + pointId + ": [" + coordX + " , " + coordY + "]"); } break; // 处理完节点段后退出外层循环 } } } catch (Exception e) { throw new Exception("Error: 打开或读取文件", e); } finally { if (scannerLectura != null) { scannerLectura.close(); } } return puntoMap; } // 测试示例 public static void main(String[] args) { try { PuntoFileReader reader = new PuntoFileReader(); Map<Integer, Punto> puntoMap = reader.puntosFichero(new File("你的文件路径.txt")); // 通过ID获取对应Punto,模拟"p1""p2"的使用方式 Punto p1 = puntoMap.get(1); System.out.println("Punto 1: " + p1); } catch (Exception e) { e.printStackTrace(); } } }
关键修正点
- 用Map替代ArrayList:实现PointID与Punto对象的关联,满足通过ID访问对应点的需求
- 修复循环逻辑:原代码内层循环的
tmp不会更新,会导致无限循环,现在改为每次读取新token判断是否为EOF - 修正对象存储错误:原代码错误地将整数ID添加到
ArrayList<Punto>中,现在正确创建Punto对象并存入Map - 资源安全处理:添加
finally块确保Scanner被正确关闭,避免资源泄漏
内容的提问来源于stack exchange,提问作者Grefuwan
相关产品推荐
相关产品推荐

