Friday, January 29, 2016

Topic 31: Enumerations in Java

  • In its simplest form, an enumeration is a list of named constants.

  • In Java, an enumeration defines a class type. That means, an enumeration can have constructors, methods, and instance variables.

  • An enumeration is created using the enum keyword. For example, here is a simple enumeration that lists various apple varieties:

enum Apple
{
Jonathan, GoldenDel, RedDel, Winesap, Cortland
}

The identifiers Jonathan, GoldenDel, and so on, are called enumeration constants. Each is implicitly declared as a public, static final member of Apple. Furthermore, their type is the type of the enumeration in which they are declared, which is Apple in this case. Thus, in the language of Java, these constants are called self-typed, in which “self” refers to the enclosing enumeration.

  • We can create a variable of enumeration type. We declare and use an enumeration variable in much the same way as we do one of the primitive types. For example, this declares ap as a variable of enumeration type Apple: 

    Apple ap;

Because ap is of type Apple, the only values that it can be assigned (or can contain) are those defined by the enumeration. For example, this assigns ap the value RedDel:

ap = Apple.RedDel; //RedDel is preceded by Apple.

  • Two enumeration constants can be compared for equality by using the = = relational operator. For example, this statement compares the value in ap with the GoldenDel constant:

if(ap == Apple.GoldenDel) // ...

  • An enumeration value can also be used to control a switch statement. Of course, all of the case statements must use constants from the same enum as that used by the switch expression. For example, this switch is perfectly valid:

switch(ap) {
case Jonathan:
// ...
case Winesap:
// ...

Notice that in the case statements, the names of the enumeration constants are used without being qualified by their enumeration type name. This is because the type of the enumeration in the switch expression has already implicitly specified the enum type of the case constants. There is no need to qualify the constants in the case statements with their enum type name. In fact, attempting to do so will cause a compilation error.

  • When an enumeration constant is displayed, such as in a println( ) statement, its name is output. For example, given this statement:

System.out.println(Apple.Winesap); //the name Winesap is displayed.

  • All enumerations automatically contain two predefined methods: values( ) and valueOf( ). Their general forms are shown here:

public static enum-type[ ] values( )

public static enum-type valueOf(String str)

The values( ) method returns an array that contains a list of the enumeration constants. The valueOf( ) method returns the enumeration constant whose value corresponds to the string passed in str. In both cases, enum-type is the type of the enumeration. For example:

// use values()
Apple allapples[] = Apple.values();
for(Apple a : allapples)
System.out.println(a);

// use valueOf()
ap = Apple.valueOf("Winesap");
System.out.println("ap contains " + ap);

  • In Java, enumeration is a class type and each enumeration constant is an object of its enumeration type. When we define a constructor for an enum, the constructor is called when each enumeration constant is created. Also, each enumeration constant has its own copy of any instance variables defined by the enumeration. For example, consider the following version of Apple:

// Use an enum constructor, instance variable, and method.
enum Apple {
Jonathan(10), GoldenDel(9), RedDel(12), Winesap(15), Cortland(8);

//Instance variable
private int price; // price of each apple

// Constructor
Apple(int p) { price = p; }

//Instance method
int getPrice() { return price; }
}

Apple ap;

// Display price of Winesap.
System.out.println("Winesap costs " + Apple.Winesap.getPrice() + " cents.\n");
// Display all apples and prices.
for(Apple a : Apple.values())
System.out.println(a + " costs " + a.getPrice() + " cents.");

When the variable ap is declared, the constructor for Apple is called once for each constant that is specified. Notice how the arguments to the constructor are specified, by putting them inside parentheses after each constant, as shown here:

Jonathan(10), GoldenDel(9), RedDel(12), Winesap(15), Cortland(8);

These values are passed to the p parameter of Apple( ), which then assigns this value to price.

Because each enumeration constant has its own copy of price, we can obtain the price of a specified type of apple by calling getPrice( ). For example:

Apple.Winesap.getPrice()

  • An enum can have two or more constructor overloaded forms, just as can any other class. For ex:

// Use an enum constructor.
enum Apple {
Jonathan(10), GoldenDel(9), RedDel, Winesap(15), Cortland(8);
private int price; // price of each apple


// Constructor
Apple(int p) { price = p; }

// Overloaded constructor
Apple() { price = -1; }

}

Notice that in this version, RedDel is not given an argument. This means that the default constructor is called, and RedDel’s price variable is given the value –1.

  • Enumeration can’t inherit another class and also cannot be a superclass. This means that an enum can’t be extended.This come with one exception, i.e. all enumerations automatically inherit one: java.lang.Enum. This class defines several methods that are available for use by all enumerations.

    We can obtain a value that indicates an enumeration constant’s position, called its ordinal value, in the list of constants by calling the ordinal( ) method, shown here:

final int ordinal( )

It returns the ordinal value of the invoking constant. Ordinal values begin at zero. Thus, in the Apple enumeration, Jonathan has an ordinal value of zero, GoldenDel has an ordinal value of 1, RedDel has an ordinal value of 2, and so on.

We can compare the ordinal value of two constants of the same enumeration by using the compareTo() method. It has this general form:

final int compareTo(enum-type e)

Here, enum-type is the type of the enumeration, and e is the constant being compared to the invoking constant. Remember, both the invoking constant and e must be of the same enumeration. If the invoking constant has an ordinal value less than e’s, then compareTo( ) returns a negative value. If the two ordinal values are the same, then zero is returned. If the invoking constant has an ordinal value greater than e’s, then a positive value is returned.

We can compare for equality an enumeration constant with any other object by using equals( ), which overrides the equals( ) method defined by Object. Simply having ordinal values in common will not cause equals() to return true if the two constants are from different enumerations. Remember, we can compare two enumeration references for equality by using = =.

Apple ap, ap2, ap3;
// Obtain ordinal values using ordinal().
for(Apple a : Apple.values())
System.out.println(a + " " + a.ordinal());


ap =  Apple.RedDel;
ap2 = Apple.RedDel;

// Demonstrate compareTo() and equals()
if(ap.compareTo(ap2) < 0)
System.out.println(ap + " comes before " + ap2);

if(ap.equals(ap2))
System.out.println(ap + " equals " + ap2);
if(ap == ap2)
System.out.println(ap + " == " + ap2);


Click for NEXT article.

 

Please feel free to correct me by commenting your suggestions and feedback.

No comments:

Post a Comment