Enums

by Trevor Page on September 27, 2012

Enums is a neat topic that applies to most programming languages (not just Java)!

Enums

What is an Enum?

It’s short for Enumerated Type, which just means that Java allows you to define your own special variable type. This becomes helpful when you would like to express something in more human readable terms. For example, let’s say you would like to make an application that allows you to play a card game, like poker. Wouldn’t it be nice if you could assign numeric values to all of the cards? Like so:

  • 2 -> 10 = 2 -> 10
  • Jack = 11
  • Queen = 12
  • King = 13
  • Ace = 14

Well, enums make this a piece of cake. Let’s create a Card enum!

package com.howtoprogramwithjava.business;
 
public enum CardValue
{
  TWO(2),
  THREE(3),
  FOUR(4),
  FIVE(5),
  SIX(6),
  SEVEN(7),
  EIGHT(8),
  NINE(9),
  TEN(10),
  JACK(11),
  QUEEN(12),
  KING(13),
  ACE(14);
 
  private int cardValue;
 
  private CardValue (int value)
  {
    this.cardValue = value;
  }
 
  public int getCardValue() {
    return cardValue;
  }
}

Voila! We’ve now outlined what a CardValue enum could look like, now let’s define what the Card’s Suit could look like:

package com.howtoprogramwithjava.business;
 
public enum Suit
{
  HEARTS,
  SPADES,
  CLUBS,
  DIAMONDS;
}

Alrighty, so we have now defined what a Suit and CardValue looks like as Enums in Java. Things that you should note are that Enums need to have a package or private scoped constructor, if you try to specify anything else, Java will fail the compilation of your code. You can also get away with not defining a constructor at all (like I did with the Suit Enum). This is because you aren’t meant to instantiate Enums, you’re supposed to reference the values in a static way, as they are meant to be constant values.

If you don’t quite understand what I mean when I say that the values should be referred to in a static way, just hang in there, I’ll have an example soon. First, let’s put the CardValue and Suit together into a Card object to pull everything together.

package com.howtoprogramwithjava.business;
 
public class Card
{
  private Suit suit;
  private CardValue cardValue;
 
  public Card (CardValue cardValue, Suit suit)
  {
    this.cardValue = cardValue;
    this.suit = suit;
  }
 
  public Suit getSuit()
  {
    return suit;
  }
 
  public void setSuit(Suit suit)
  {
    this.suit = suit;
  }
 
  public CardValue getCardValue()
  {
    return cardValue;
  }
 
  public void setCardValue(CardValue cardValue)
  {
    this.cardValue = cardValue;
  }
}

Okay nothing new going on in that code, it’s a standard Object that defines some private (encapsulated) variables that are made publicly visible via getter and setter methods. But you can see how this makes sense right? A Card is simply made up of a CardValue and a Suit! Just like real life! Don’t you just love Object Oriented Programming?

Okay, so let’s talk a bit more about what I meant when I said that the Enums have to have a package or private level constructor. I said that this is because you shouldn’t be able to instantiate the class, as the contained values should be referenced in a static fashion. Let’s see what I mean with an example:

package com.howtoprogramwithjava.business;
 
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
 
public class Deck
{
  private ArrayList<Card> deck;
 
  public Deck ()
  {
    this.deck = new ArrayList<Card>();
    for (int i=0; i<13; i++)
    {
      CardValue value = CardValue.values()[i];
 
      for (int j=0; j<4; j++)
      {
        Card card = new Card(value, Suit.values()[j]);
        this.deck.add(card);
      }
    }
 
    Collections.shuffle(deck);
 
    Iterator<Card> cardIterator = deck.iterator();
    while (cardIterator.hasNext())
    {
      Card aCard = cardIterator.next();
      System.out.println(aCard.getCardValue() + " of " + aCard.getSuit());
    }
  }
}

Wow! A lot going on here. The basic concept of this code is that we want to properly represent a Deck of Cards. So, we all know that there are 52 Cards in a Deck right? So this means that we should iterate through all of our CardValues and Suits in order to match them up with each other. We do this by referring to the Enums in a static way like so:

CardValue.values();
// and
Suit.values();

If you hover your mouse over the values() part of the code in your IDE, you’ll see that when you invoke the values() method, you’ll get an Array that represents every value inside the Enum. So if I were to invoke Suit.values(), I would get an array of values back like so:

[HEARTS, SPADES, CLUBS, DIAMONDS]

In that exact order. It’s important to mention that it’s in that exact order because that’s the order in which they are defined in the Suit object. Java is very particular about the way it does things. It doesn’t like to give you back an Array in any random order.

So, when you keep that in mind, it helps to understand what I’m doing in this Deck code. As you scan through the Deck code you’ll notice that I have two for loops and one is nested inside the other. The outer for loop is running from 0 to 12 and the inner loop is running from 0 to 3. So, this means that we’ll ensure that we get every single combination of CardValue and Suit.

Note: I said 0 to 12 even though the for loop says i=0; i<13; i++. I'll leave it to you to think things through and try to understand why this is. If you absolutely give up and can't figure it out (even after debugging the code), then I invite you to ask me in the comments section for the answer and I'll be happy to explain).

So, at this point we'll just have a Deck of Cards that are neatly in order. So, like any good Deck of cards, we want to mix them up so they're random right? Well, lucky for us, we used an ArrayList Collection to represent our Deck of Cards, and inside the Collection class, we have a helper method called shuffle. This method is used to randomize ANY List Collection. Neat :)

So, after we've shuffled our Deck let's just output what the Deck or Cards looks like!

THREE of SPADES
FIVE of SPADES
SIX of DIAMONDS
QUEEN of SPADES
FIVE of DIAMONDS
THREE of DIAMONDS
SEVEN of CLUBS
SIX of SPADES
QUEEN of HEARTS
KING of CLUBS
KING of SPADES
SEVEN of SPADES
KING of HEARTS
THREE of HEARTS
JACK of CLUBS
FOUR of DIAMONDS
TEN of DIAMONDS
TWO of CLUBS
EIGHT of SPADES
FOUR of CLUBS
EIGHT of CLUBS
TEN of SPADES
JACK of SPADES
THREE of CLUBS
NINE of CLUBS
SEVEN of HEARTS
NINE of DIAMONDS
ACE of CLUBS
SEVEN of DIAMONDS
FIVE of CLUBS
TWO of SPADES
TWO of HEARTS
KING of DIAMONDS
EIGHT of DIAMONDS
NINE of SPADES
QUEEN of DIAMONDS
EIGHT of HEARTS
JACK of DIAMONDS
TEN of HEARTS
JACK of HEARTS
TEN of CLUBS
ACE of SPADES
FIVE of HEARTS
ACE of DIAMONDS
TWO of DIAMONDS
FOUR of SPADES
SIX of CLUBS
SIX of HEARTS
FOUR of HEARTS
NINE of HEARTS
ACE of HEARTS
QUEEN of CLUBS

And there you go, a nice neat shuffled Deck. Don't you just love Object Oriented programming? You see how I was able to explain a real world scenario of a Deck of Cards by using the names of the actual types in Java? It makes your code so much more readable and understandable.

Okay folks, as always, it's been a pleasure writing up this Java tutorial for you on Enums today. So if you could do me a huge favour and share my content by clicking one (or all) of this social sharing buttons on the top left of your screen right now? Like/tweet/stumble away my friends and spread the word, every vote helps me out big time and it helps others to find my site and learn how to become a programmer (isn't that a gift you'd love to share?). hehe, okay, take care everyone and I look forward to seeing you all in the next tutorial!




Top 7 Tools Java Professionals Use Daily
The best part is, 85% of these tools are FREE
Download this 1-page PDF that will show you exactly how to get your hands on all these tools today.

{ 8 comments… read them below or add one }

Javin September 30, 2012 at 1:30 am

As always great post Trevor. No one can deny importance of Enum in Java programming and on top of that Enum is much powerful in Java than language like C or C++. I have also shared some thoughts on this on my post 10 Example of Enum in Java , which kind of complement your post. Looking forward for some more good post.

Javin

Reply

Trevor Page September 30, 2012 at 9:05 am

I would highly recommend Javin’s tutorial to any readers who want to learn more about Enums, it’s a great article!

Reply

Eric Jablow October 1, 2012 at 10:56 am

Try not to use indexed for loops. Create your deck with:

this.deck = new ArrayList();
for (CardValue card: CardValue.values()) {
for(Suit suit: Suit.values()) {
deck.add(new Card(card, suit));
}
}

There is no need for any of the integer indexes.
The Card class should also be immutable. I’d hate to see card.setCardValue(CardValue.ACE) be successful.
You should also consider having factory methods for constructing decks instead of using the constructor, and having shuffle be a separate method. After all, suppose you want to construct a deck for pinochle, where there are 2 each of ACE-NINE, or a Las Vegas Blackjack deck with 8 full decks of cards? You might also want to provide access to the deck of cards as if it were a stack; you want to deal the cards by popping cards off the stack.

Reply

Eric Jablow October 1, 2012 at 12:13 pm

One more thing: Collections.shuffle() is insufficiently random for most purposes. The default source of randomness is almost certainly Java’s linear congruential PRNG, which has 48-bits of randomness, and so has only 2^48 patterns. However, to adequately shuffle a deck of cards, you need at least 52 factorial patterns, and 52! ≫ 2^48. Use the Collections.shuffle(List, Random) overload, and use a cryptographical-quality random number source.

Please don’t laugh about that; insufficiently-random PRNGs have caused embarrassing failures in science. In one occassion, a particle physics experiment disagreed with a numerical simulation, solely because the PRNG violated the 7th-order spectral test, and a Monte Carlo integration gave nonsense.

Reply

Trevor Page October 1, 2012 at 2:07 pm

Eric! I admire your ambition to help me out by sharing these valuable observations. You sound like a smart developer with a good head on his shoulders :)

I admit that these tips are all correct, and, should anyone actually be creating a card game, these things should be taken into consideration.

The goal of this article is to provide my audience (of whom are at the beginner level) some fundational knowledge on topics in Java. So the goal is to present the information in a manner that won’t confuse them, this will help to keep them on track in learning. I fear that going into this level of detail with some example programs will have the opposite effect and scare them away.

When I do create tutorials that require this kind of in-depth analysis, I will categorize them as “advanced”. But as I mentioned before, I thank you for your dedication to providing a very complete and thorough solution.

Reply

Eric Jablow October 2, 2012 at 3:30 pm

Yes, I did include too much, and it was peripheral to the main thrust of your post. On the other hand, I do think it important to use the modern foreach loop instead of the indexed loop. In pseudocode, the block
// For each rank
//For each suit
//Create a Card
//And add it to the deck
is much simpler than the indexed alternative.

I would say that even before one starts to code, one should figure out the purpose of the code. What does one do with a deck of cards? One deals from it. So, a deck should have a deal method. It should have a shuffle method too. On the other hand, separate methods to build pinochle decks, blackjack decks, or euchre decks can wait until the programmer has that task. So a class skeleton could be:

public class Deck {
public Deck() {…}
public void shuffle() {…}
public Card deal() {…}
}

Each of these items could and should have tests, and you could ask your students how they would test them. You might get answers like:

A new deck should have 52 cards.
No card should appear twice in a deck.
Shuffling a deck twice should give differently-ordered decks.
Dealing a card when there are no cards left should do something unusual. Okay, that usually means throwing an exception, which may be new to your students. But let them come up with the idea first.

Reply

Paxton Crissey September 24, 2013 at 2:37 pm

How do you add multiple people added to blackjack game.

Reply

Jarred June 25, 2014 at 2:35 pm

How would you output this from main? New to Java trying to figure it out.

Reply

Leave a Comment

Powered by sweet Captcha

Previous post:

Next post: