У меня проблема с реализацией компаратора TreeSet. У меня есть простая игра, в которой животные ходят по доске, каждый ход они делают одно движение, если они умирают по какой-либо причине, они помечаются как «мертвые», помещаются в список «Мертвые организмы», а затем удаляются из «очереди» дерева. " в этом фрагменте кода (я не могу удалить их сразу, потому что перебираю набор деревьев):
for(Organism org : DeadOrganisms){
queue.remove(org);
}
Проблема в том, что некоторые из них вообще не удаляются, даже несмотря на то, что в конце каждого хода они возвращаются в список DeadOrganisms из-за того, что помечены как «мертвые». Будучи уверенным, что .remove вызывается при каждом включении мертвого организма, я почти уверен, что проблема заключается в классе Comparator:
class MyComparator implements Comparator<Organism> {
@Override
public int compare(Organism o1, Organism o2) {
if (o1.getName().equals(o2.getName())) {
return 0;
}
if (o1.getInitiative() > o2.getInitiative()) {
return -1;
} else if (o1.getInitiative() == o2.getInitiative()) {
if (o1.getAge() > o2.getAge()) {
return -1;
} else {
return 1;
}
} else {
return 1;
}
}
}
Предполагается, что компаратор проверяет, совпадает ли имя o1 (уникальное для каждого персонажа на доске) с именем o2, а остальная часть кода предназначена для сортировки набора деревьев по инициативе персонажа или возрасту, если инициатива равна. Фрагмент кода абстрактного класса Organism, из которого происходят все символы:
public abstract class Organism {
protected int lastxpos;
protected int lastypos;
private final World myworld;
private int strength;
private int initiative;
private int xPos;
private int yPos;
private int age;
private String name;
Color color;
private boolean isdead;
public Organism(World world, String name){
this.name = name;
this.color = Color.RED;
this.strength = 0;
this.initiative = 0;
this.xPos = 0;
this.yPos = 0;
this.age = 0;
this.isdead = false;
this.myworld = world;
}
Я знаю, что либо делаю что-то не так, либо неправильно понимаю, как работают TreeSets (или и то, и другое), но я не могу понять, что именно. Я также знаю, что .remove
удаляет элемент e такой, что (o==null ? e==null : o.equals(e))
Так что в моем понимании это роль
if (o1.getName().equals(o2.getName())) {
return 0;
}
в моем классе Comparator, но, возможно, я что-то неправильно понимаю. Я был бы очень признателен за любую помощь в этом.
@ РЕДАКТИРОВАТЬ Я не знаю, имеет ли это значение, но пока я тестирую его на одном типе животных, с тем же возрастом и инициативой, поэтому единственная разница между всеми животными - это их имя.
@EDIT2 Я также заметил, что если удаляемый организм находится первым в "очереди" набора деревьев, то в методе сравнения после вызова queue.remove(org) "org" никогда не оказывается по сравнению с 1-м объектом в наборе деревьев (он же сам) только со вторым, третьим и т. д.
@EDIT3 Для пользователя NPE в комментариях: Объявление очереди:
public class World extends JPanel{
*_declarations of some variables_*
private final TreeSet<Organism> queue;
Инициализация очереди:
public World(int sizeX, int sizeY) {
this.queue = new TreeSet<>(new MyComparator());
*_ommitting rest of constructor code_*
}
Объявление и инициализация DeadOrganisms:
public void EndTurn(){
List<Organism> DeadOrganisms = new ArrayList<>();
*_omitting rest of the EndTurn code_*
}
queue
иDeadOrganisms
. - person NPE   schedule 13.05.2018