2015-03-14 2 views
-1

У меня есть две карты ArrayLists, карта с карточками, а затем «запуск» Карт (карты - это объекты.) Я пытаюсь инициировать «запуск» Карт и удалять их карты из руки.ArrayList Remove Is not Removing Object

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

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; 
} 
+0

Проверьте возвращаемое значение 'handCard.remove (newCard)', чтобы узнать, удалил ли он карту. – JNYRanger

+0

Это не так. handCard.remove (newCard) показывает arrayList.size в 7, а затем return handCard также отображает возвращаемый размер 7. Таким образом, removeCard, кажется, получает правильную Карту, но застрял где-то посередине. – Michelle

+0

Что такое handCard? Вы не указали, где/как это объявлено. Вы уверены, что ссылка на объект, возвращаемая 'runToAdd.next()', фактически является той же ссылкой (не обязательно теми же данными), хранящейся в 'handCard'? – JNYRanger

ответ

2

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

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

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

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

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

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

Позвольте мне знать результат теста, и я буду обновлять ответ с тем, что вы должны смотреть на следующей.

+0

А ты великолепный! Еще иначе, в моем коде, я создавал новую Карту и добавлял * это * к runToAdd ArrayList, а не к Карте в массиве HandList. Спасибо огромное! – Michelle

+0

NP, рад, что я мог бы помочь. ;) –

1

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

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

Ломая, что вниз:

  • Это может быть просто, что элемент не в списке ... в каком-то смысле.

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

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

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


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

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


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

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

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

+0

Это фантастический момент, который, как мне хотелось бы, я узнал, когда я начал программировать. Ваша переопределенная реализация 'equals()' в java имеет решающее значение, если вы не хотите, чтобы сравнения ссылок все время. – JNYRanger

Смежные вопросы