用于静态值的Java Enum或HashMap

Ros*_*iar 11 java enums

我正在生成一个CSV文件以及CTL文件以供使用sqlldr.CTL文件需要知道我要加载的列的名称,我的CSV文件需要知道这些字段的默认值.

/*
 * Models a line in the CSV file
 */
public class CSVRecord {
  ...
}

/*
 * Models the CTL file
 */
public class ControlFile {
    ...
}
Run Code Online (Sandbox Code Playgroud)

这两个类初始化并在内部使用CSVExportFile,我有两种方法:

1.枚举

public enum Columns {
    ID("1"),
    NAME("Bob"),
    ...
}
Run Code Online (Sandbox Code Playgroud)

2. HashMap

public class CSVExportFile {
    private HashMap<String, String> columns;

    public CSVExportFile() {
        columns = new HashMap<String, String>();
        columns.put("ID", "1");
        columns.put("Name", "Bob");
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

HashMap降低了列的范围,将意味着他们只能内部使用CSVExportFile.我不打算扩展这个功能(所有的课程都是final),所以我不确定我能enum获得什么.

对于每种方法有什么争论,这是一个特殊情况,其中一个是优越的,还是一种优越的方式?

Old*_*eon 7

我总是会enum在这里使用一个enum天生的命令,而Map不是.

通过使用,enum您可以从枚举本身生成CTL文件,并使用这些enum值作为工厂来填充您的csv文件.

class MyObj {

    final String foreName;
    final String surname;

    public MyObj(String foreName, String surname) {
        this.foreName = foreName;
        this.surname = surname;
    }

    public String getForeName() {
        return foreName;
    }

    public String getSurname() {
        return surname;
    }

}

enum Column {

    Forename {

                @Override
                String fromMyObj(MyObj it) {
                    return it.getForeName();
                }
            },
    Surname {

                @Override
                String fromMyObj(MyObj it) {
                    return it.getSurname();
                }
            },;

    abstract String fromMyObj(MyObj it);

    static String asSelectStatement(Set<Column> columns, String tableName) {
        return join(columns, ",", "SELECT ", " FROM " + tableName);
    }

    static String asCSVHeader(Set<Column> columns) {
        return join(columns, ",");
    }

    static String asCSV(Set<Column> columns, MyObj it) {
        return join(columns, (Column a) -> a.fromMyObj(it), ",");
    }

    private static String join(Set<Column> columns, String between) {
        return join(columns, new StringJoiner(between));
    }

    private static String join(Set<Column> columns, String between, String prefix, String suffix) {
        return join(columns, new StringJoiner(between, prefix, suffix));
    }

    private static String join(Set<Column> columns, StringJoiner joined) {
        return join(columns, (Column a) -> a.name(), joined);
    }

    private static String join(Set<Column> columns, Function<Column, String> as, String between) {
        return join(columns, as, new StringJoiner(between));
    }

    private static String join(Set<Column> columns, Function<Column, String> as, String between, String prefix, String suffix) {
        return join(columns, as, new StringJoiner(between, prefix, suffix));
    }

    private static String join(Set<Column> columns, Function<Column, String> as, StringJoiner joined) {
        for (Column c : columns) {
            joined.add(as.apply(c));
        }
        return joined.toString();
    }

    // Also simple to auto-populate prepared statements, build INSERT statements etc.
}

public void test() {
    Set<Column> columns = EnumSet.of(Column.Forename, Column.Surname);
    System.out.println("As Select: " + Column.asSelectStatement(columns, "MyTable"));
    System.out.println("As CSV Header: " + Column.asCSVHeader(columns));
    MyObj it = new MyObj("My Forename", "My Surname");
    System.out.println("As CSV: " + Column.asCSV(columns, it));
}
Run Code Online (Sandbox Code Playgroud)