使用 Avro java api 动态插入枚举符号

Dynamically insert Enum symbols with Avro java api

我正在为具有枚举字段的 java class 编写架构。我正在使用 java 模式生成器,如下所示:

public Schema schema = SchemaBuilder
    .record("MyRecord").namespace("my.name.space")
    .name("myEnum").type().enumeration("MyEnumClass").namespace("enum.name.space")
        .symbols("S1", ..., "S1000").noDefault()
    .endRecord()

问题是 MyEnumClass 中有数百个 Enum 值。 class 可以从我的代码访问。如何在不手动输入的情况下将它们动态插入 .symbles()

您可以为您的 class 自动创建 avro 架构。

例如

枚举:

public enum TestEnum {
    VAL1,
    VAL2,
    VAL3
}

Class 枚举字段:

public class TestClass {
    public TestEnum testEnum;

    public TestClass() {

    }

    public TestClass(TestEnum testEnum) {
        this.testEnum = testEnum;
    }

    public TestEnum getTestEnum() {
        return testEnum;
    }

    public void setTestEnum(TestEnum testEnum) {
        this.testEnum = testEnum;
    }
}

正在生成架构:

Schema schema = ReflectData.get().getSchema(TestClass.class);

结果:

{
  "type": "record",
  "name": "TestClass",
  "namespace": "q42698247",
  "fields": [
    {
      "name": "testEnum",
      "type": {
        "type": "enum",
        "name": "TestEnum",
        "symbols": [
          "VAL1",
          "VAL2",
          "VAL3"
        ]
      }
    }
  ]
}

正如 DontPanic 在他的回复中所说,您可以使用反射直接从枚举类型构建。但是,如果您没有要使用的 Java 枚举类型,还有另一种方法。

有问题的方法 EnumBuilder.symbols(String... symbols) 使用了 'vararg' String 参数。有关可变参数的详细信息,请参阅此。 http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html#varargs

实际上,数组可以转换为可变参数,只要类型匹配。所以,你可以这样做(下面的代码没有用编译器验证,但你明白了)

List<String> enumElements = new ArrayList<String>();
for (int i = 1; i <= 1000; i++) {
  enumElements.add("S"+i);
};
String[] enumElementsArray = enumElements.toArray(new String[0]);

public Schema schema = SchemaBuilder
    .record("MyRecord").namespace("my.name.space")
    .name("myEnum").type().enumeration("MyEnumClass").namespace("enum.name.space")
        .symbols(enumElementsArray).noDefault()
    .endRecord();