This week's book giveaway is in the Mac OS forum. We're giving away four copies of a choice of "Take Control of Upgrading to Yosemite" or "Take Control of Automating Your Mac" and have Joe Kissell on-line! See this thread for details.
I am trying to write an Enum that will hold the column names of an Excel sheet. I am able to associate the column number and column name with the Enum values.
The data for the columns is take from a custom class object. The class has getter and setter method to access its data holding fields.
So if I like to print a column data, I check the column number from the Enum and then call the corresponding setter method in my custom class.
Say if I am printing column 0, then I call a setter method named getProduct() and print it's data.
I wish to make this check done by the Enum itself. i.e. If I call a generalized method named getData() on a particular Enum (say PRODUCT) then it should in turn call the getProduct() method and return its value.
Is there a way I can achieve it.
I am pasting a similar code I wrote to visualize my need.
I don't know whether it is a good idea, but you could code your enum similar to this:
Then use it in the following way: colEnum.printField(student));.
You can declare an abstract method to do whatever you need and implement it differently for individual enums. But so tight coupling between the enum and the functionality does not look right to me. Though there are many ways to twist this basic scheme around, I still usually prefer the good old switch statement in cases similar to this. Good thing about the scheme I've shown is that the compiler forces you to redefine the abstract method for any of your enums. In a switch statement, that is generally detected only at runtime.
Using an abstract method that you override in each of the constants, like Martin's code shows, is the usual way to do this. Instead of a method that prints data you can of course also use a method that returns a property of the object. The return type will have to be a common super type of all property types though. The marks would need to be returned as a String, or the return type would need to be Object to allow both Strings and Integers to be returned.
The only thing I would change in that code is the getTopic method:
Both your implementation and mine use an Iterator over topicHierarchySet (yours when creating the ArrayList), but my implementation a) doesn't iterate over the entire set but only the necessary part, and b) doesn't create the List object. Both implementations work just fine, mine is slightly better in both memory and time.
And I would probably store the return value of ResultColumn.values() in a ResultColumn instead of calling the method twice, but that too is only to improve performance slightly.
Oh, and a for not using the return value of order() as the column number. I don't know if you did this on purpose, but order() should only be used in data structures like EnumSet and EnumMap, definitely not for custom code. The reason is simple - if you add an enum constant in the middle, the return value of order() changes, and that can lead to unexpected results.