简而言之,我有一个名为 PersonList 的对象,它具有 Person 对象的列表。我创建了 PersonList 的 2D 数组来模拟 map ,并在该 map 中随机放置和移动 Person 对象。但是,我在从 PersonLists 的 2D 数组中删除 Person 时遇到问题。同时,似乎同一个 Person 永远不会被添加到 2D 数组中的同一位置,即使它移动到那里。
我已尽力创建以下内容的小版本。我有一种感觉,我错过了一些明显的东西。我也对更好地实现该系统的方法持开放态度,因为这可能是效率最低的方法。
人:
public class Person {
private int id;
private int[] pos = new int[2];
public Person(int id) { this.id = id; }
public int getId() { return id; }
public int[] getPos() { return pos; }
public void setPos(int x, int y) { pos[0] = x; pos[1] = y; }
public boolean equals(Object obj) {
if (obj == null) { return false; }
if (obj == this) { return true; }
if (obj.getClass() != getClass()) { return false; }
Person rhs = (Person) obj;
return id == rhs.getId();
}
public int hashCode() { return id; }
}
人员列表:
import java.util.*;
public class PersonList {
List<Person> listPersons = new ArrayList<Person>();
PersonList() {}
public void add(Person p) { listPersons.add(p); }
public void remove(Person p) { listPersons.remove(p); }
public int getSize() { return listPersons.size(); }
}
现在,我又多了一个类来控制一些 Person,并包含 PersonList 的 2D 数组。它看起来像这样:
import java.util.*;
public class Control {
List<Person> persons = new ArrayList<Person>();
PersonList[][] pmap;
//numPeople is the number of Person objects to use
//size is the size of the pmap (used as both length and width)
public Control(int numPeople, int size) {
pmap = new PersonList[size][size];
//Initialize all PersonList objects within array
for(int y = 0; y < size; y ++) {
for(int x = 0; x < size; x ++) {
pmap[x][y] = new PersonList();
}
}
for(int i = 0; i < numPeople; i ++) {
persons.add(new Person(i));
}
// Defined below
placePersons();
}
// Randomly place Person on the pmap
private void placePersons() {
Iterator<Person> i = persons.listIterator();
while(i.hasNext()) {
Person p = i.next();
int x, y;
// Random method to obtain valid position within pmap stored in x and y
p.setPos(x, y);
pmap[x][y].add(p);
}
}
//Move person from "src" on pmap to "dest" on pmap
private void movePerson(Person p, int[] src, int[] dest) {
pmap[src[0]][src[1]].remove(p);
pmap[dest[0]][dest[1]].add(p);
p.setPos(dest[0], dest[1]);
}
//Makes every person wander around the pmap
public void wander() {
for(Person p : persons) {
int[] xy = new int[2];
// Random method to obtain valid position within pmap stored in xy
movePerson(p, p.getPos(), xy);
}
}
}
想象一下我在循环中启动“Control.wander()”。我遇到一个问题,人员没有正确地从 pmap 中删除。我已经打印了一个网格,其中包含 pmap 中每个 PersonList 的大小,并且数字永远不会减少。但是,它们的增加不会超过“人员”列表中的人员数量。
也就是说,看起来它们无法被删除,但是即使他们移动到了 pmap 中的同一位置,也不会多次将其添加到该位置。
我的问题是否立即显而易见,或者理论上这应该有效?
如有任何问题,请随时提出。感谢您的帮助,我真的很感激。
编辑:我添加了一些更改 - 我现在使用迭代器而不是 for-each 循环,并且我为 Person 定义了一个简单的 hashCode 方法。作为测试,我在 PlayerPos 中添加了一个方法 (getFirst()),该方法返回列表中的第 0 个对象,如果没有任何对象,则返回 null。
在 movePerson 中,我有类似的内容:
System.out.println(p + " and " + pmap[src[0]][src[1]].getFirst());
它预期打印两个匹配的 id(我在测试中只使用 1 个人)。我还在 PersonList 的 remove(Person p) 函数本身中添加了相同的行。然而,通常情况下,“getFirst()”结果将显示 null。在我对 movePerson 进行测试后立即调用remove(Person p),那么为什么它会返回一些内容,但在 PersonList 本身中什么也没有返回呢?这是否更能说明我的问题?感谢迄今为止的所有帮助。
编辑2:我也尝试过将PersonList的listPersons公开并直接操作它,但我似乎仍然遇到同样的问题。
编辑3:通过更多测试,在movePerson中,我已经打印出了每行之间的src和dest pmap的大小,并且似乎它已被正确地从src pmap中删除,但是在添加到dest之后,src pmap的大小再次增加。我已经三次检查了我的 add 函数(这是一个简单的单行函数)并确保数组索引是正确的。怎么会发生这种事?
最佳答案
private void movePerson(Person p, int[] src, int[] dest) {
pmap[src[0]][src[1]].remove(p);
pmap[dest[0]][src[1]].add(p);
p.setPos(dest[0], dest[1]);
}
应该是
private void movePerson(Person p, int[] src, int[] dest) {
pmap[src[0]][src[1]].remove(p);
pmap[dest[0]][dest[1]].add(p); //fix on this line
p.setPos(dest[0], dest[1]);
}
因此,人员似乎被添加到了他们认为的位置之外的位置。
另请注意,您不需要将 src
传递给该方法,因为 Person
已经跟踪它的位置:
private void movePerson(Person p, int[] dest) {
int[] pos = p.getPos();
pmap[pos[0]][pos[1]].remove(p);
pmap[dest[0]][dest[1]].add(p);
p.setPos(dest[0], dest[1]);
}
编辑:每当您重写equals()
时,请确保重写hashCode()
。缺少此功能可能会干扰 List
方法 remove()
。其他人提到了这一点,但答案被删除了。
出于您的目的,hashCode()
应该只返回 id
假设这是唯一的。例如,不要将位置因素考虑在内 - 您希望一个人
成为一个身份,无论他们身在何处。对此进行测试,如果仍然无法正常工作,请更新您的问题。
关于java - 二维列表数组的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6836695/