У меня есть два списка ArrayList, набор карт и затем «серия» карт (карты - это объекты). Я пытаюсь инициировать «серию» карт и удалить эти конкретные карты из руки.

У меня такой же код в другом методе, и он отлично работает. По какой-то причине приведенный ниже код не удаляет из Hand карты «бега», и я не могу понять почему. Отладчик показывает метод, передающий правую карту; Любые идеи?

private ArrayList<ArrayList<Card>> meldDesktop;     

public void addMeldRun(ArrayList runToAdd, Hand playerHand, Player player){

    this.meldDesktop.add(runToAdd);

    //after adding the run to the meld desktop, remove them from the player's
    //hand and get points
    Iterator<Card> testRoll = runToAdd.iterator();
    while (testRoll.hasNext()){
        int points = 0;
        Card removeCard = testRoll.next();
        playerHand.removeCard(removeCard);
        points = removeCard.pointValue() + points;
        player.setScore(points);

    }
}

 public ArrayList removeCard (Card newCard){
    handCard.remove(newCard);
    //Collections.sort(handCard);
    return handCard;
}
-1
Michelle 14 Мар 2015 в 04:12

2 ответа

Лучший ответ

Вероятно, проблема в том, что объекты карты каким-то образом копируются / клонируются, поэтому они не те же объекты, что и в объекте playerHand. Таким образом, они не проходят проверку на равенство в handCard.remove (newCard);

Вы можете проверить это с помощью:

boolean removed = handCard.remove(newCard);
System.out.println(newCard.pointValue() + " removed = " + removed);

Скорее всего, проблема связана с тем, как вы добавляете карточки в объект runToAdd.

Также вы можете улучшить цикл while или даже лучше использовать расширенный цикл for:

int points = 0;
for (Card removeCard : testRoll){
    playerHand.removeCard(removeCard);
    points += removeCard.pointValue();
}
player.setScore(points);

Сообщите мне результат теста, и я обновлю ответ, указав, на что вам следует взглянуть дальше.

2
Michael Hobbs 14 Мар 2015 в 01:31

Вы не предоставили достаточно информации для правильного диагноза / объяснения вашей конкретной проблемы.

Однако есть только одно правдоподобное объяснение того, что List.remove(elem) не работает. То есть elem не находится "в" списке ... в соответствии с определенной семантикой "в" согласно javadocs.

Разбивая это:

  • Возможно, элемент просто отсутствует в списке ... в любом смысле.

  • Также может быть, что элемента нет в списке, потому что реализация метода equals(Object) неверна для семантики «в списке», которую вы ожидаете.

Спецификация для remove в List API заключается в том, что он использует метод equals(Object). Если elem.equals(obj) равно true для некоторого obj, находящегося в списке, то этот объект будет удален.

Но вот в чем загвоздка. Реализация по умолчанию equals(Object), унаследованная от java.lang.Object, заключается в простом сравнении ссылок на объекты. Если вы не переопределите equals(Object) для своего класса Card И ваше приложение создаст несколько экземпляров (скажем) «Короля треф» ... тогда remove может потерпеть неудачу, потому что вы пытался удалить не тот.


Другой способ решить эту проблему - использовать отладчик для пошагового выполнения метода remove (наблюдение за локальными переменными и т. Д.), Чтобы увидеть, что на самом деле происходит. В частности, найдите точку, в которой он должен совпадать с элементом (Card), который вы хотите удалить.

Однако я надеюсь, что это лишь подтвердит то, что я сказал выше.


Вывод заключается в том, что код должен выполнять одно из следующих действий:

  • убедитесь, что «Король клубов» создается только один раз; т.е. никогда не копируйте его, никогда не клонируйте, никогда не new другой экземпляр и т. д. ИЛИ

  • переопределить equals(Object) для сравнения объектов Card по значению; то есть, чтобы все экземпляры «Короля треф» рассматривались как равные. Очевидно, семантика будет зависеть от правил игры, которую вы моделируете ... но вам нужно продумать это самостоятельно.

2
Stephen C 14 Мар 2015 в 01:43