Working with Enums Flashcards

1
Q

Working with Enums

A
  • An enumeration, or enum for short, is like a fixed set of constants.
  • Using an enum is much better than using a bunch of constants because it provides typesafe checking.
  • With numeric or String constants, you can pass an invalid value and not find out until runtime.
  • With enums, it is impossible to create an invalid enum value without introducing a compiler error.
  • Enumerations show up whenever you have a set of items whose types are known at compile time.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Creating Simple Enums

A

To create an enum, declare a type with the enum keyword, a name, and a list of values, as shown below:

// public or package access
// keyword: enum
// name of enum: Season
public enum Season {
    WINTER, SPRING, SUMMER, FALL;
    // enum values (comma separated)
    // Semicolon optional for simple enums
}

the semicolon at the end of the list is optional.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

> [!NOTE]
Enum values are considered constants and are commonly written using snake case.
For example, an enum declaring a list of ice cream flavors might include values like VANILLA, ROCKY_ROAD, MINT_CHOCOLATE_CHIP, and so on.

A
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Using an enum

A
var s = Season.SUMMER;
System.out.println(Season.SUMMER);      // SUMMER
System.out.println(s == Season.SUMMER); // true
  • As you can see, enums print the name of the enum when toString() is called.
  • They can be compared using == because they are like static final constants.
  • In other words, you can use equals() or == to compare enums, since each enum value is initialized only once in the Java Virtual Machine (JVM).
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Cannot extends enum

A
public enum ExtendedSeason extends Season {} // DOES NOT COMPILE
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Calling the values(), name(), and ordinal() Methods

A

An enum provides a values() method to get an array of all of the values.
You can use this like any normal array, including in a for-each loop:

for (var season: Season.values()) {
    System.out.println(season.name() + " " + season.ordinal());
}

Output:
~~~
WINTER 0
SPRING 1
SUMMER 2
FALL 3
~~~

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

if ( Season.SUMMER == 2) {} // DOES NOT COMPILE

A

You can’t compare an int and an enum value directly anyway since an enum is a type, like a Java class, and not a primitive int.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Calling the valueOf () Method

A

Another useful feature is retrieving an enum value from a String using the valueOf() method. This is helpful when working with older code or parsing user input. The String passed in must match the enum value exactly, though.

Season s = Season.valueOf("SUMMER"); // SUMMER
Season t = Season.valueOf("summer"); // IllegalArgumentException
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Using Enums in switch Statements

A

Enums can be used in switch statements and expressions.

Season summer = Season.SUMMER;
switch(summer) {
    case WINTER:
        System.out.print("Get out the sled!");
        break;
    case SUMMER:
        System.out.print("Time for the pool!");
        break;
    default:
        System.out.print("Is it summer yet?");
}

we just typed the value of the enum rather than writing Season.WINTER. After all, the compiler already knows that the only possible matches can be enum values. Java treats the enum type as implicit. In fact, if you were to type case Season.WINTER, it would not compile.

Season summer = Season.SUMMER;
var message = switch(summer) {
    case Season.WINTER -> "Get out the sled!"; // DOES NOT COMPILE
    case 0 -> "Time for the pool!";            // DOES NOT COMPILE
    default -> "Is it summer yet?";
};
System.out.print(message);
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Adding Constructors, Fields, and Methods

A
1:  public enum Season {
2:      WINTER("Low"), SPRING("Medium"), SUMMER("High"), FALL("Medium");
3:      private final String expectedVisitors;
4:      private Season(String expectedVisitors) {
5:          this.expectedVisitors = expectedVisitors;
6:      }
7:      public void printExpectedVisitors() {
8:          System.out.println(expectedVisitors);
9:      } 
10: }

There are a few things to notice here.
* On line 2, the list of enum values ends with a semicolon (;). While this is optional when our enum is composed solely of a list of values, it is required if there is anything in the enum besides the values.
* Lines 3–9 are regular Java code. We have an instance variable, a constructor, and a method. We mark the instance variable private and final on line 3 so that our enum properties cannot be modified.
* All enum constructors are implicitly private, with the modifier being optional. This is reasonable since you can’t extend an enum and the constructors can be called only within the enum itself. In fact, an enum constructor will not compile if it contains a public or protected modifier.

   What about the parentheses on line 2? Those are constructor calls, but without the new keyword normally used for objects. The first time we ask for any of the enum values, Java constructs all of the enum values. After that, Java just returns the already constructed enum values.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Although it is possible to create an enum with instance variables that can be modified, it is a very poor practice to do so since they are shared within the JVM. When designing an enum, the values should be immutable.

A
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q
public enum OnlyOne {
    ONCE(true);
    private OnlyOne(boolean b) {
        System.out.print("constructing,");
    }
}

public class PrintTheOne {
    public static void main(String[] args) {
        System.out.print("begin,");
        OnlyOne firstCall = OnlyOne.ONCE; // Prints constructing,
        OnlyOne secondCall = OnlyOne.ONCE; // Doesn't print anything
        System.out.print("end");
    }
}
A

Output :

begin,constructing,end

  If the OnlyOne enum was used earlier in the program, and therefore initialized sooner, then the line that declares the firstCall variable would not print anything.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

How do we call an enum method?

A

That’s easy, too: we just use the enum value followed by the method call.

Season.SUMMER.printExpectedVisitors();

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q
public enum Season {
    WINTER {
        public String getHours() { return "10am-3pm"; }
    },
    SPRING {
        public String getHours() { return "9am-5pm"; }
    },
    SUMMER {
        public String getHours() { return "9am-7pm"; }
    },
    FALL {
        public String getHours() { return "9am-5pm"; }
    };
    public abstract String getHours();
}
A

If we forget to implement the method for one of the values, we get a compiler error:

The enum constant WINTER must implement the abstract method getHours()
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

What if we don’t want each and every enum value to have a method?

A

We can create an implementation for all values and override it only for the special cases.

public enum Season {
    WINTER {
        public String getHours() { return "10am-3pm"; }
    },
    SUMMER {
        public String getHours() { return "9am-7pm"; }
    },
    SPRING, FALL;
    public String getHours() { return "9am-5pm"; }
}

We only code the special cases and let the others use the enum-provided implementation.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

An enum can even implement an interface, as this just requires overriding the abstract methods:

public interface Weather { int getAverageTemperature(); }

public enum Season implements Weather {
    WINTER, SPRING, SUMMER, FALL;
    public int getAverageTemperature() { return 30; }
}
A
17
Q

Just because an enum can have lots of methods doesn’t mean that it should. Try to keep your enums simple. If your enum is more than a page or two, it is probably too long. When enums get too long or too complex, they are hard to read.

A
18
Q

You might have noticed that in each of these enum examples, the list of values came first. This was not an accident. Whether the enum is simple or complex, the list of values always comes first.

A