0

I've got an Object in Java representing the contents of a database, like so:

public Database {
    int varA;
    String varB;
    double varC;
}

Now I'm trying to select and order certain elements for forther processing, but I want to make it configurable, so I created an enum which represents all attributes of the object like

public enum Contents {
    VarA,
    VarB,
    VarC;
}

So now when I create a selection like

Contents[] select = { Contents.VarC, Contents.VarB };

i want to generate a List of String values representing the actual database contents from this. Now the only Implementation i could think of is switching for each entry in the selection, with has a pretty ugly quadratic complexity...

public List<String> switchIT(Database db, Contents[] select) {
    List<String> results = new ArrayList<String>();

    for (Contents s : select) {
        switch(s) {
            case VarA:
                results.add(db.varA.toString());
                break;
            //go on...
        }
    }

    return results;
}

is there a more direct way to map between enum and dynamic object values? Or in more general terms: What is the best way to select values from an object dynamically?

4

1 回答 1

3

Use the power of Java enums, which are fully-fledged classes.

public enum Contents {
  VarA { public String get(Database d) { return d.getVarA(); } },
  VarB { public String get(Database d) { return d.getVarB(); } },
  VarC { public String get(Database d) { return d.getVarC(); } };
  public String get(Database d) { return ""; }
}

Your client code then becomes

public List<String> switchIT(Database db, Contents[] select) {
  List<String> results = new ArrayList<String>();
  for (Contents s : select) results.add(s.get(db));
  return results;
}

A more concise, but slower, solution would be to use a single implementation of get based on reflection and use the name of the enum member to generate the appropriate getter name:

public enum Contents {      
  VarA, VarB, VarC;

  private final Method getter;

  private Contents() {
    try {
      this.getter = Database.class.getMethod("get"+name());
    } catch (Exception e) { throw new RuntimeException(e); }
  }
  public String get(Database d) {
    try {
      return (String) getter.invoke(d); 
    } catch (Exception e) { throw new RuntimeException(e); }
  }
}
于 2012-10-14T09:23:07.877 回答