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

如何从50000行CSV生成Java Enum以创建EnumSet?

从CSV自动生成Java枚举类以创建EnumSet的解决方案

由于Java枚举是编译期确定的静态类型,无法在运行时动态生成新的枚举常量,所以要实现从CSV生成50000行枚举且保留EnumSet支持,最靠谱的方案是在编译前自动生成枚举类源码。以下是具体实现步骤:

一、核心思路

编写一个简单的代码生成工具,读取CSV文件内容后直接输出符合Java语法的枚举类源码,再将该工具集成到项目构建流程中,确保编译前自动完成枚举类的生成。

二、具体实现步骤

1. 准备CSV文件

假设你的CSV格式(带表头)如下:

code,name,population
PARIS,巴黎,2161000
LONDON,伦敦,9002488
...

其中code列对应枚举常量名(需符合Java标识符规则:无特殊字符、以字母开头),其余列为枚举的属性字段。

2. 编写枚举生成工具

可以用原生Java或Apache Commons CSV(更适合处理复杂CSV格式)实现,以下是示例代码:

依赖(若用Apache Commons CSV)

如果用Maven,在pom.xml中添加:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-csv</artifactId>
    <version>1.10.0</version>
</dependency>

生成工具代码

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

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;

public class VilleEnumGenerator {
    public static void main(String[] args) throws Exception {
        // 1. 配置参数
        String csvPath = "src/main/resources/ville.csv";
        String targetPackage = "com.example.city";
        String targetEnumName = "Ville";
        String outputPath = "src/main/java/com/example/city/Ville.java";

        // 2. 读取CSV并构建枚举内容
        StringBuilder enumContent = new StringBuilder();
        // 生成包声明和类定义
        enumContent.append(String.format("package %s;\n\n", targetPackage));
        enumContent.append(String.format("public enum %s {\n", targetEnumName));

        // 解析CSV
        try (CSVParser parser = CSVParser.parse(
                Paths.get(csvPath),
                StandardCharsets.UTF_8,
                CSVFormat.DEFAULT.withHeader().withTrim()
        )) {
            int lineCount = 0;
            for (CSVRecord record : parser) {
                String enumConstName = record.get("code");
                String cityName = record.get("name");
                int population = Integer.parseInt(record.get("population"));

                // 生成枚举常量行
                enumContent.append(String.format("    %s(\"%s\", %d)", enumConstName, cityName, population));
                // 最后一行不加逗号
                if (lineCount != parser.getRecordNumber() - 2) {
                    enumContent.append(",");
                }
                enumContent.append("\n");
                lineCount++;
            }
        }

        // 生成构造方法和Getter
        enumContent.append(";\n\n");
        enumContent.append("    private final String name;\n");
        enumContent.append("    private final int population;\n\n");
        enumContent.append(String.format("    %s(String name, int population) {\n", targetEnumName));
        enumContent.append("        this.name = name;\n");
        enumContent.append("        this.population = population;\n");
        enumContent.append("    }\n\n");
        enumContent.append("    public String getName() {\n");
        enumContent.append("        return name;\n");
        enumContent.append("    }\n\n");
        enumContent.append("    public int getPopulation() {\n");
        enumContent.append("        return population;\n");
        enumContent.append("    }\n");
        enumContent.append("}\n");

        // 3. 写入目标文件
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(outputPath))) {
            writer.write(enumContent.toString());
        }
    }
}

3. 集成到构建流程(自动生成)

为了避免每次手动运行工具,可以将其集成到Maven/Gradle的构建阶段,确保编译前自动生成枚举类。

Maven集成示例

在pom.xml中添加exec-maven-plugin,让它在generate-sources阶段执行生成工具:

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>generate-ville-enum</id>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>java</goal>
                    </goals>
                    <configuration>
                        <mainClass>com.example.city.VilleEnumGenerator</mainClass>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

执行mvn compile时,工具会自动运行并生成枚举类,之后正常编译即可使用。

三、注意事项

  • 确保CSV中的code列符合Java标识符规则,若不符合需在工具中添加转换逻辑(比如将空格替换为下划线、特殊字符转义)。
  • 50000行枚举会生成较大的类文件,但Java对枚举类大小没有硬性限制,只要编译环境内存足够即可。
  • 若需要更新枚举内容,只需修改CSV文件,重新构建项目即可自动更新枚举类。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 19:03:37