Cole Dooley Cole Dooley - 3 months ago 12
Java Question

Most efficient way to build a deck of cards (ArrayLists, Arrays, etc.)?

So I am new to Java and Started using ArrayLists before arrays.
I like that they are more similar to Python lists, and understand that ArrayLists contain only objects rather than primitives, which in my mind, makes them more useful for lists containing multiple types.
I wrote this to show how I'd make a deck of cards (everything is static just for this example):

public class Deck {

private static Scanner input = new Scanner(System.in);
private static Random newRan = new Random();

private static final List RANKS = new ArrayList(Arrays.asList("ace", 2, 3, 4, 5, 6, 7, 8, 9,
10, "jack", "queen", "king"));
private static final List SUITS = new ArrayList(Arrays.asList("hearts", "diamonds", "clubs",
"spades"));

private static List makeDeck() {
List result = new ArrayList();
for (Object i : SUITS) {
for (Object j : RANKS) {
result.add(Arrays.asList(i, j));
}
}
return result;
}

public static void main(String[] args) {
List deck = makeDeck();

for (Object i : deck) {
System.out.println(i);
}
}
}


I believe this may slow down the program, as I have read elsewhere, but I was wondering what would be a better, more conventional or clean way of accomplishing this?
All constructive criticism welcomed.

(Again, I'd like to say that I wrote this little code just to demonstrate my question about arrays and arrayLists and their functionality, a quick example.)

Answer

Enums!

Enums are great for things like Card Suits and Ranks. Much better than collections of Strings, actually. For example...

enum Suit {
    HEARTS, SPADES, DIAMONDS, CLUBS;
}

Enums can have their own properties like any other class, too, but that's something that you can read up on separately. The tall-and-short of Enums is that they are singletons in runtime and each is intrinsically unique by definition. These are very handy properties.

Next, I advise that you implement a formal Card class. A Card is more than a list of properties. You'd want something like this as a base for your Card class:

class Card {
   private final Suit suit;
   private final Rank rank;

   public Card(Suit suit, Rank rank) {
       this.suit = suit;
       this.rank = rank;
   }

   public Suit getSuit() { return this.suit; }

   public Rank getRank() { return this.rank; }
}

Users of your code will thank you for this, versus remembering whether a list's first element is the suit or the rank of the card.

You'd have to refactor your makeDeck method to use these new enums and classes, but the general approach would remain the same. Iterate over all the Suits and, in that iteration, iterate over all the ranks and create a new Card instance for each iteration. That way, you're making a new Card with each value of Rank and Suit. You'd end up with a full deck.

Now, the question you want to ask yourself is this: Is a Deck merely a List of Cards, or does it merit its own class? There is no right or wrong answer; it's up to you and what your program needs. Maybe just using a List of Cards is perfectly fine.

Oh, and on that note (and maybe this is just a bit of a nit-pic), if you want a "List of Cards", make it a List of Cards. List<Card> is better than just List. Generic types are your friend!