Much of my personal interaction with ENUM class was limited to making a list of constants and calling the members during some test assertion level. I couldn’t see it past a different form of list holding some values in upper class just like an array or list. The hidden beauty of ENUM has largely been unknown until it was revealed in a web scrapping hackathon. But before, let’s take a quick look at what ENUM is all about.
What is ENUM?
An ENUM type is a special data type that enables for a variable to be a set of predefined constants. Because they are static final constants, the names of an ENUM type's fields are in uppercase letters. It is primarily used to represent a fixed set of constants.
Some key features of ENUM are:
· Java Enum internally extends Enum class – it is not written explicitly with “extend” keyword
· Every Enum constant is always public, static, final -- hence, written in all upper case
· Each of the constant represents an object of enum type they are declared in – In this example, MONDAY will act as object of enum type Days, having attributes dayName and dayNumber of data type String and integer respectively
· ENUM class body can include
o Constructors – enum constructor is executed as many times as the number of constants in it when the enum is summoned somewhere. In the example above, WEDNESDAY attributes were not defined at constant level. Therefore had to create a constructor with no input arguments.
o Methods -- methods are written to define behavioral aspect of constants. Methods can be as simple as getting attribute value of a constant (like getDayName()) or something more functional like isItWeekend() or remainingDaysOfTheWeek()
o Main method – enum class can have main methods of its own as shown in line 49
Java programming language ENUM types are much more powerful than that of other programming languages. The compiler automatically adds some special methods when it creates an ENUM. For example, they have a static values method that returns an array containing all of the values of the ENUM in the order they are declared. This method is commonly used in combination with the for-each construct to iterate over the values of an ENUM type. Besides defined method, some of the other methods provided by Java Enum class are discussed below:
1. String name() : This method returns the name of enum constant, which is exactly as declared in its enum declaration.
2. int ordinal() : This method returns index of this enumeration constant
3. String toString() : This method returns a String object representing this enumeration constant. This method is same as name() method.
4. boolean equals(Object obj) : This method returns true if the specified object is equal to this enum constant , otherwise return false.
5. int compareTo(E obj) : This method “compares” this enum with the specified object for order. Enum constants are only comparable to other enum constants of the same enum type.
6. Class <E> getDeclaringClass() : This method returns the Class object corresponding to this enum constant’s enum type. A "Months" enum has been declared on the right-side code. In line 27 and 28, the Contants' respective declaring class printed out to be "class Days" for variable "day" (having value Days.Sunday) and "class Months" for variable "month" (having value Months.MAR).
In a recent web-scrapping hackathon, the teams were tasked with finding recipes that are safe for consumption for different type of morbidity patients. For example, someone with Diabetes cannot eat sugar, anything deep fried, white bread, etc. were listed in an Elimination List and we had to find out recipes that didn’t contain any items from the elimination list for diabetic patient. Few of the challenges faced were:
Ø Multi-form verbiage to denote same ingredient à recipe ingredient containing the word sugar would have been disregarded right away. But some recipes use “sugar substitute”. So filtering out recipe based on the word “sugar” alone wasn’t correct
Ø Elimination item that were not necessarily an ingredient à deep fried food will not have any ingredient name “deep fried” but will have oil. Now oil itself cannot be an elimination factor. Hence, not only had to read the ingredients of recipe, but also the recipe instructions looking for mentioning of those words in various forms like “deep fry”, “deep-fried”, etc
Initially, we were trying to read recipe ingredients and filter them out using if-else but that was making the whole code big and repetitive with multiple lines of if, else-if blocks.
Alternatively, to be inclusive of all the combinations of words for a given elimination list, a teammate applied the concept of Enum in the following way:
Code Explanation:
1) The strings members of each elimination item was passed as a String array in the constructor (line 45)
2) isExcluded method was defined to iterate through each the constant String arrays. A further breakdown would be:
A. In line 50, the first value for DiabetesExclusions.values() is PROCESSED_GRAINS
B. In line 51 exclusion.ingredients would return a list of strings inside PROCESSED_GRAINSà("cream of rice", "rice flour", "rice rava", "corn sugar" à which will then be captured by String[] elements
C. In line 53 – 56, each of the ingredients in the elements[] array would be checked to see if it starts with “^”. If it does, then it will be considered an ingredient itself and that we shouldn’t filter out this element when compared with recipe ingredient.
D. In line 57 – 62: if the constant ingredient is a match with the recipe ingredient being read at the moment, then return true since this recipe ingredient is found in the elimination list
In this way, the whole elimination process got condensed to a function with around 10 lines instead of 30+ lines of codes when we were trying to write through if else process.
A lot more could be done with Enum when applied aptly. Enum by itself or in combination with switch statement and others could make concise yet powerful codes.
Thank you for reading. Hope this was an informative read.
Comments