生成动态城市数据集合:用 Record + CSV 解析替代静态枚举

云芳君_2960

云芳君_2960

2026-06-16

959人浏览

原创

本文讲解如何用 java 记录类(record)和 csv 解析替代无法动态扩展的 enum,高效管理数万条城市数据,并支持 enumset 类似的集合操作。

本文讲解如何用 java 记录类(record)和 csv 解析替代无法动态扩展的 enum,高效管理数万条城市数据,并支持 enumset 类似的集合操作。

在 Java 中,enum 的本质是编译期固定的类型安全常量集合——它的所有枚举常量必须在源码中显式声明,且 JVM 加载后不可增删。当你面对 50,000 行 CSV 城市数据时,硬编码 enum Ville { ... } 不仅维护成本极高,更违背了设计原则:运行时数据 ≠ 编译时常量。此时,正确的技术路径不是“强行用 CSV 生成 enum”,而是放弃 enum,改用面向数据建模的现代 Java 方案。

✅ 推荐方案:record + List(兼顾简洁性与功能性)

Java 14+ 引入的 record 是为此类场景量身定制的:它以极简语法声明不可变数据载体,自动提供构造器、字段访问器、equals/hashCode 和 toString,完美替代手写 POJO。

// 定义不可变城市记录(字段名与 CSV 列严格对应)
public record Ville(
    String pays,
    String codePostal,
    String nom,
    String region,
    String departement,
    String numDepartement,
    String prefecture,
    String codeCommune,
    String latitude,
    String longitude
) {}

? 提示:若需数值计算(如地理距离),建议将 latitude/longitude 声明为 double 类型,并在构造时解析(Double.parseDouble(lat)),避免字符串重复转换。

? 从 CSV 构建城市集合(使用 Apache Commons CSV)

引入依赖(Maven):

QuickBooks Mileage CSV
QuickBooks Mileage CSV

使用 qbo-mileage CLI 及用户凭证,从 Airtable、Outlook 或 Google Calendar 记录生成 QuickBooks Online 里程 CSV 文件。

下载
<dependency><groupid>org.apache.commons</groupid><artifactid>commons-csv</artifactid><version>1.10.0</version></dependency>

加载 CSV 并构建 List:

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;

import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

public class VilleLoader {
    public static List<ville> loadFromCsv(String csvPath) throws IOException {
        List<ville> villes = new ArrayList();
        try (CSVParser parser = CSVParser.parse(
                Paths.get(csvPath).toFile(),
                java.nio.charset.StandardCharsets.UTF_8,
                CSVFormat.DEFAULT.withFirstRecordAsHeader())) {

            for (CSVRecord record : parser) {
                villes.add(new Ville(
                    record.get("pays"),
                    record.get("codePostal"),
                    record.get("nom"),
                    record.get("region"),
                    record.get("departement"),
                    record.get("numDepartement"),
                    record.get("prefecture"),
                    record.get("codeCommune"),
                    record.get("latitude"),
                    record.get("longitude")
                ));
            }
        }
        return villes;
    }
}</ville></ville>

? 模拟 EnumSet 行为:使用 EnumSet 的替代集合策略

虽然不能直接用 EnumSet(它专为 enum 设计),但可通过以下方式获得同等或更强能力:

需求 推荐方案 说明
全量遍历 & 快速查找 List + Stream villes.forEach(System.out::println);按名称查找:villes.stream().filter(v -> v.nom().equals("Paris")).findFirst()
去重 & 有序存储 TreeSet 实现 Comparable(如按 nom 排序),或传入 Comparator.comparing(Ville::nom)
高性能存在性检查 HashSet 需确保 Ville 的 equals/hashCode 正确(record 已自动实现)
保持插入顺序 + 去重 LinkedHashSet 兼顾顺序与唯一性

示例:构建可排序的城市集合

// 按城市名升序排列
Set<ville> sortedVilles = new TreeSet(
    Comparator.comparing(Ville::nom)
);
sortedVilles.addAll(VilleLoader.loadFromCsv("villes.csv"));</ville>

⚠️ 关键注意事项

  • 不要尝试动态生成 enum 类:通过字节码生成(如 ByteBuddy)或注解处理器虽技术可行,但会破坏 JVM 类型安全、增加构建复杂度,且无法解决“运行时数据变更”需求。
  • CSV 字段映射务必校验:生产环境需添加空值检查、格式验证(如邮编是否为数字)、异常处理(NumberFormatException 等)。
  • 内存优化考虑:50,000 条记录对 JVM 内存压力较小,但若后续扩展至百万级,建议采用流式处理(Stream)或数据库分页加载。
  • 线程安全:record 实例天然不可变,但集合本身(如 ArrayList)非线程安全。多线程读取推荐 Collections.unmodifiableList(villes)。

✅ 总结

用 record 替代 enum 不是妥协,而是面向数据本质的正确抽象。它让你摆脱编译期束缚,拥抱运行时灵活性,同时享受 Java 语言演进带来的简洁性与安全性。配合成熟的 CSV 库和 Collections Framework,你不仅能完美复现 EnumSet 的功能,还能轻松扩展过滤、排序、持久化等企业级能力——这才是处理大规模结构化数据的现代 Java 实践。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

10657

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

7782

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

6772

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1144

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

948

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1396

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2809

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

20111

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1235

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.7万人学习