我的目标是生成一个枚举以创建一个EnumSet。如果我编写枚举,这部分就可以工作。我不想编写50000行的枚举,而是想CSV导入50000行。当我尝试用CSV导入替换我编写的枚举时,麻烦就开始了。
package VilleEnumSet;
public class VilleEnumSet {
//ENUM SANS CSV
enum Ville {
Paris("FR", "75000", "Paris", "Ile de France", "Paris", "75", "Paris", "751", "48.8534", "2.3488"),
Lyon("FR", "69000", "Lyon", "Auvergne-Rhone-Alpes", "Rhone", "69", "Lyon", "691", "45.7485", "4.8467"),
Marseille("FR", "13000", "Marseille", "Provence-Alpes-Cote d'Azure", "Bouches-du-Rhone", "13", "Marseille", "133", "43.2969", "5.3811"),
Montpellier("FR", "34000", "Montpellier", "Occitanie", "Herault", "34", "Montpellier", "343", "43.6109", "3.8764");
//ATTRIBUTS
private final String pays;
private final String codePostal;
private final String nom;
private final String region;
private final String departement;
private final String numDepartement;
private final String prefecture;
private final String codeCommune;
private final String latitude;
private final String longitude;
//CONSTRUCTEUR
private Ville(String pays, String codePostal, String nom, String region, String departement, String numDepartement,
String prefecture, String codeCommune, String latitude, String longitude) {
this.pays = pays;
this.codePostal = codePostal;
this.nom = nom;
this.region = region;
this.departement = departement;
this.numDepartement = numDepartement;
this.prefecture = prefecture;
this.codeCommune = codeCommune;
this.latitude = latitude;
this.longitude = longitude;
}
//GETTERS
public String getPays() {
return pays;
}
public String getCodePostal() {
return codePostal;
}
public String getNom() {
return nom;
}
public String getRegion() {
return region;
}
public String getDepartement() {
return departement;
}
public String getNumDeprtement() {
return numDepartement;
}
public String getPrefecture() {
return prefecture;
}
public String getCodeCommune() {
return codeCommune;
}
public String getLatitude() {
return latitude;
}
public String getLongitude() {
return longitude;
}
//TOSTRING
public String toString() {
return String.format("%-40s%-10s\n", "Pays: " + pays, "Code Postal: " + codePostal)
+ String.format("%-40s%-10s\n", "Nom: " + nom, "Region: " + region)
+ String.format("%-40s%-10s\n", "Departement: " + departement, "Num Departement: " + numDepartement)
+ String.format("%-40s%-10s\n", "Prefecture: " + prefecture, "Code Commune: " + codeCommune)
+ String.format("%-40s%-10s\n\n", "Latitude: " + latitude, "Longitude: " + longitude);
}
}
}
package VilleEnumSet;
import java.util.EnumSet;
import java.util.Iterator;
import VilleEnumSet.VilleEnumSet.Ville;
public class MainVilleEnumSet {
public static void main(String[] args) {
// Creating an EnumSet using allOf()
EnumSet<Ville> villes = EnumSet.allOf(Ville.class);
// Creating an iterator on games
Iterator<Ville> iterate = villes.iterator();
// Message
System.out.println("EnumSet: " + "\n");
while (iterate.hasNext()) {
System.out.println(iterate.next());
}
}
}
我的代码返回这个:
EnumSet:
Pays: FR Code Postal: 75000
Nom: Paris Region: Ile de France
Departement: Paris Num Departement: 75
Prefecture: Paris Code Commune: 751
Latitude: 48.8534 Longitude: 2.3488
Pays: FR Code Postal: 69000
Nom: Lyon Region: Auvergne-Rhone-Alpes
Departement: Rhone Num Departement: 69
Prefecture: Lyon Code Commune: 691
Latitude: 45.7485 Longitude: 4.8467
对于CSV结构,每一列对应于类"VilleEnumSet"中的一个属性。
我不知道该怎么办。我已经寻求帮助,但许多人建议切换到我不想做的列表。
枚举旨在表示编译时已知的一小组值。这些值的名称旨在在您的源代码中使用,如Bill K的正确答案中所述。
那不符合你的情况。
您在运行时加载了大量值。表示这些值是自定义类的目的。对自定义类的对象进行分组是Java集合框架的目的,其中包含列表、集合、队列、映射等。
如果您的自定义类的主要目的是透明且不可变地通信数据,请将您的类定义为记录。编译器隐式创建构造函数getter,equals
record Ville (String pays, String codePostal, String nom, String region, String departement, String numDepartement, String prefecture, String codeCommune, String latitude, String longitude) {}
顺便说一下,从Java16开始,记录可以在方法中本地定义,也可以嵌套在类中,或者单独定义。(枚举和接口也是如此。)
当您的CSV库导入每一行输入时,实例化记录类的一个对象。添加到集合对象,可能是List
的实现。在实现可比较
接口后,您可以选择使用NavigableSet
/SortedSet
。
如果您的输入在运行时发生变化,您可以根据另一个数据导入将对象集合替换为新对象。使用枚举,您可以尝试任何成员字段的值,但不能添加或删除命名的枚举对象。
虽然您绝对不会为此使用枚举,但实际上有一个有效的用例,所以如果其他人来这里,这是值得回答的。
对您的问题的实际直接回答是,您希望以渐进方式生成枚举的代码。一种方法(错误的方法)是编写一个预编译器来手动构建文件,方法是将类的开头作为常量字符串发出,将csv文件中每组数据的重复行发出,然后将类的结尾作为另一个常量字符串发出。在启动实际的java编译器之前,您的buildfile会调用这个预编译器。
这是有问题的-它将需要一个预编译步骤,并且可能不会与您的IDE集成。
更正确的方法是创建注释处理器。可以在编译代码之前处理注释,并允许您将任意代码插入文件中。
如果您的注释在枚举中,您的注释处理器可以发出如下行:
Paris("FR", "75000", "Paris", "Ile de France", "Paris", "75", "Paris", "751", "48.8534", "2.3488"),
文件的其余部分将是一个实际的java类文件,其中包含一个注释,该注释会导致调用处理器。
注释处理器通过命令行开关传递给java编译器,如“javac-处理器(fullClassName)”。
这样做的好处是,你可以告诉IDE这是一个注释处理器,它将确保在你的CSV文件中添加一条记录使枚举立即可用。它还可以防止生成临时源文件(当人们试图手动编辑它们时,这些几乎总是会带来麻烦)