0

I am working on creating a bag of cards for a blackjack game in my CS course. This particular project requires that I create a bag to hold my 52 cards. Keep in mind that I am trying to assure that there are 4 types of each card, Queens, Kings, Jacks, and Aces all included. I keep getting an error in my main: Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer; at Main.main(Main.java:14)

If anyone can please help me to get this bag running properly, it would be greatly appreciated.

Here is my code:

public class Bag<T> 
{
    T[] cards;
    private final int DEFAULT_CAPACITY = 52;
    private int numberOfEntries;

    public Bag()
    {
        this.cards = (T[]) new Object[DEFAULT_CAPACITY];
        numberOfEntries = DEFAULT_CAPACITY;
    }

    public int getCurrentSize()
    {
        return numberOfEntries;
    }

    public boolean isFull()
    {
        return numberOfEntries == DEFAULT_CAPACITY;
    }

    public boolean isEmpty()
    {
        return numberOfEntries == 0;
    }

    public boolean add(T newItem)
    {
        boolean result = true;
        if(isFull())
        {
            result = false;
        }

        else
        {
            cards[numberOfEntries] = newItem;
            numberOfEntries++;
        }

        return result;
    }

    public boolean remove()
    {
        boolean result = true;
        if(numberOfEntries > 0)
        {
            numberOfEntries--;
        }
        else
            result = false;

        return result;
    }

    public void clear()
    {
        numberOfEntries = 0;
    }

    public int getNumOf(T anItem)
    {
        int count = 0;

        for(int i = 0; i < cards.length; i++)
        {
            if(anItem.equals(cards[i]))
            {
                count++;
            }
        }

        return count;
    }

    public boolean contains(T anItem)
    {
        boolean found = false;

        for (int i = 0; !found && (i < numberOfEntries); i++)
        {
            if(anItem.equals(cards[i]))
            {
                found = true;
            }
        }

        return found;
    }

    public T Grab()
    {
        int random = (int)(Math.random() * DEFAULT_CAPACITY);
        if(!isEmpty())
        {
            cards[random] = null;
            numberOfEntries--;
            return cards[random];
        }

        else
            return null;
    }

    public int getFrequencyOf(T anItem)
    {
        int counter = 0;

        for(int i = 0; i < numberOfEntries; i++)
        {
            if(anItem.equals(cards[i]))
            {
                counter++;
            }
        }

        return counter;
    }

}

public class Main {

    public static void main(String[] args)
    {
        //Accesses the Bag class
        Bag<Integer> bag = new Bag<Integer>();

        //Sets up 52 cards (13*4). 4 of each type
        for (int i = 1; i <= 13; i++) 
        {

            for (int j = 1; j <= 4; j++) {
                bag.cards[i*j] = i;
                //if the card is an ace and not equal to 1
                if(i == 1)
                    bag.cards[i*j] = 11;
                //handles the king, queen, and jack cards
                else if (i==11||i==12||i==13)
                    bag.cards[i*j] = 10;    
            }

            bag.add(1);
        }
    }
}
  • This might be helpful. http://stackoverflow.com/questions/529085/how-to-create-a-generic-array-in-java Your default array assignment should be one of the two methods indicated, either unchecked, or checked. In this case, I tried unchecked and got `an array out of bounds` exception. You need to subtract 1 from the index `i * j` as arrays start at 0. – Compass Feb 10 '15 at 21:52
  • possible duplicate of [Ljava.lang.Object; cannot be cast to \[Ljava.lang.Integer](http://stackoverflow.com/questions/27591061/ljava-lang-object-cannot-be-cast-to-ljava-lang-integer) – Radiodef Feb 10 '15 at 22:38

2 Answers2

1

Don't provide access to your T[] cards variable. Make it private and create a set method in your Bag like this:

public void set(int index, T item) {
  // assume !full AND 0 <= index < cards.length 
  this.cards[index] = item;
}

Then, instead of doing:

bag.cards[i*j] = 10;

you then do:

bag.set(i*j, 10);    

The fact that you get a class-cast exception is because type erasure: your T[] only lives at compile time. After compilation, it will just have become a Object[]. That is why your direct access cards[0] = 123 throws this exception (Integer 123 cannot be put inside a Object[]).

The set(int index, T value) I suggested works, because after compilation, that will just become set(int index, Object value), and hence: no class-cast exception.

EDIT

You can test the following quick demo:

class Bag<T> {

  private T[] cards;

  public Bag() {
    this.cards = (T[]) new Object[10];
  }

  public void set(int index, T value) {
    this.cards[index] = value;
  }

  @Override
  public String toString() {
    return "Bag{cards=" + java.util.Arrays.toString(cards) + "}";
  }

  public static void main(String[] args) {
    Bag<Integer> bag = new Bag<Integer>();
    bag.set(0, 10);
    bag.set(1, 20);
    bag.set(2, 30);
    System.out.println(bag);
  }
}

on Ideone, which will print:

Bag{cards=[10, 20, 30, null, null, null, null, null, null, null]} 

You can also simply remove the generics from your cards variable like this:

class Bag<T> {

  private Object[] cards;

  public Bag() {
    this.cards = new Object[10];
  }

  public void set(int index, T value) {
    this.cards[index] = value;
  }
}

For inspiration, you can always have a look at the source of core Java classes that resemble your own. In this case, that would be the java.util.ArrayList: http://www.docjar.com/html/api/java/util/ArrayList.java.html

Bart Kiers
  • 153,868
  • 34
  • 276
  • 272
1

You cannot cast your Object array to a an Integer array, because its not, it's an Object array. That's what your (T[]) cast is trying to do:

this.cards = (T[]) new Object[DEFAULT_CAPACITY];

You cannot instantiate an array of type T either, unless you pass in the class type explicity - see What's the reason I can't create generic array types in Java?. Possible solutions:

  • Use Object [] to store you data, i.e. private Object[] cards;
  • Use a parameterized collections type like List<T>, i.e. private List<T> cards
Community
  • 1
  • 1
Adam
  • 32,907
  • 8
  • 89
  • 126