Структуры данных - Создание сумки на Java

Я работаю над созданием набора карт для игры в блэкджек в своем курсе CS. Этот конкретный проект требует, чтобы я создал сумку для моих 52 карт. Имейте в виду, что я пытаюсь гарантировать, что есть 4 типа каждой карты: дамы, короли, валеты и тузы. Я все время получаю ошибку в основном файле: Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; нельзя преобразовать в [Ljava.lang.Integer; в Main.main (Main.java:14)

Если кто-нибудь может помочь мне заставить эту сумку работать должным образом, я был бы очень признателен.

Вот мой код:

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);
        }
    }
}

person Christian M. Garcia    schedule 10.02.2015    source источник
comment
Это может быть полезно. stackoverflow.com/ questions / 529085 / Назначение массива по умолчанию должно быть одним из двух указанных методов, не отмеченным или отмеченным флажком. В этом случае я попробовал снять флажок и получил an array out of bounds исключение. Вам нужно вычесть 1 из индекса i * j, поскольку массивы начинаются с 0.   -  person Compass    schedule 11.02.2015
comment
возможный дубликат Ljava.lang.Object; нельзя преобразовать в [Ljava.lang.Integer   -  person Radiodef    schedule 11.02.2015


Ответы (2)


Не предоставляйте доступ к вашей переменной T[] cards. Сделайте это private и создайте set метод в своем Bag следующим образом:

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

Затем вместо того, чтобы делать:

bag.cards[i*j] = 10;

тогда вы делаете:

bag.set(i*j, 10);    

Тот факт, что вы получаете исключение приведения к классу, объясняется стиранием типа: ваш T[] живет только во время компиляции. После компиляции он просто станет Object[]. Вот почему ваш прямой доступ cards[0] = 123 вызывает это исключение (целое число 123 не может быть помещено в Object[]).

Предложенный мной set(int index, T value) работает, потому что после компиляции он просто станет set(int index, Object value), и, следовательно, исключение приведения к классу отсутствует.

РЕДАКТИРОВАТЬ

Вы можете протестировать следующую быструю демонстрацию:

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);
  }
}

на Ideone, который напечатает:

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

Вы также можете просто удалить универсальные шаблоны из переменной cards следующим образом:

class Bag<T> {

  private Object[] cards;

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

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

Для вдохновения вы всегда можете взглянуть на исходный код основных классов Java, похожих на ваш собственный. В данном случае это будет java.util.ArrayList: http://www.docjar.com/html/api/java/util/ArrayList.java.html.

person Bart Kiers    schedule 10.02.2015

Вы не можете преобразовать свой массив Object в массив Integer, потому что это не массив Object. Вот что пытается сделать ваш актерский состав (T []):

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

Вы также не можете создать экземпляр массива типа T, если не передадите ясность типа класса - см. По какой причине я не могу создавать универсальные типы массивов в Java?. Возможные решения:

  • Используйте Object [] для хранения ваших данных, то есть частных карточек Object [];
  • Используйте тип параметризованных коллекций, например List<T>, i.e. private List<T> cards
person Adam    schedule 10.02.2015
comment
Да извините за путаницу - person Adam; 11.02.2015
comment
Без проблем. По сути, это выглядело как опечатка, но я не был уверен. - person Radiodef; 11.02.2015