Should I use an EnumSet?

1.5k Views Asked by At

I am trying to build a "flat file reader." These files will have several related columns, such as "Customer Name", "Telephone," etc, but the column number will be different for each flat file; also, some flat files will have columns that others don't.

I want each of these different files to be readable by the FlatFileReader class. So I created an enum for the first flat file, where the value is an index for an array.

enum Columns { NAME, TELEPHONE, PAYMENT }
...
String[] columns = new String[3];
columns[0] = line.substring(0,29); //Name
columns[1] = line.substring(30,36); //Telephone
columns[2] = line.substring(37); //Payment

So in order to get, for example, a name from the flat file, FlatFileReader would call the method:

file.get (Columns.NAME);

and FlatFileA would look for index 0. There's going to be a wide variety of flat file classes, and I would like for each to inherit the same enum so that it's consistent; the issue is that some files won't have certain columns. So I can't do NAME, TELEPHONE, PAYMENT in the parent class (or interface) if FlatFileB doesn't have a TELEPHONE column.

How could I solve this problem? Is this how an EnumSet is used? Could each child class create an EnumSet and only add the constants it needs? If I created an EnumSet and only added NAME and PAYMENT, would PAYMENT now have a value of 1 (inside the EnumSet) or would it still have the value of 2?

2

There are 2 best solutions below

0
On

EnumSet is just another implementation of the Set interface. Implementing the Set interface means it behaves just as much as a Set as any other implementation. The difference is in performance, accepted values and iteration order.

The benefit of the EnumSet is speed, the downside is that EnumSets can only have enum constants as members. Since each enum constant has a zero-based ordinal(), the EnumSet uses a bitstring representation, where each bit represents the presence/absence of an element in the set. Choosing EnumSet makes contains(All), add(All), remove(All) and retain(All) run much faster than for TreeSet and HashSet.

And no, an enum constant never changes its ordinal() (though I'm not sure whether that was what you meant).

0
On

I would suggest an ArrayList as your columns are in a sequence. I would further recommend you use an ArrayList of objects that encapsulate a Column along with details about how to gather the column from the records.

class Field {
  Columns col;
  int start;
  int length;
}

ArrayList<Field> file1Record = new ArrayList<Field>();

// You could calculate the 0 and 29 on the fly.
file1Record.add(new Field(Columns.NAME, 0, 29));
...