ArrayList.remove(Object o)不迭代内容

时间:2017-09-08 10:48:21

标签: java arraylist

所以,我现在已经在这个问题上坐了好几个小时了,而且我已经没有想法了。我查看了文档(ArrayList和Object)并阅读了很多关于ArrayList.remove(Object obj)的Stackoverflow问题,但没有任何帮助。

我尝试实现模拟(游戏?),我有一个Cell [] []来存储地图。每个Cell都有一个存储在ArrayList中的居民(Person类),每次迭代都会移动一步。当一个人移动时,我将它们添加到下一个Cell并从旧的Cell中删除它们。或者更确切地说,因为删除部分还没有工作。

我的问题:我需要帮助实现ArrayList.remove(Object obj)方法 到目前为止我得到了什么:

class Cell
{
    private final int x;
    private final int y;
    ArrayList<Person> inhabs = new ArrayList<Person>();

    /** this method is called by a Person that wants to move to another Cell **/
    public void moveMe(Person p){
        try{
            Cell northOfHere = grid.grid[y-1][x]//direction will be changed to be random
            northOfHere.add(p);
        }catch(ArrayIndexOutOfBoundsException ex){/*person falls from the edge of the world*/}

        inhabs.remove(p); //this is not working right
    }

    public void add(Person p){
        inhabs.add(p);
    }
}

班主任:

class Person extends Object
{
    private int health;
    private int strength;
    private int food;
    private final int nation;

    @Override
    public boolean equals(Object obj){
        if(obj == null){return false;}
        if(obj == this){return true;}
        if(!(obj instanceof Person)){return false;}

        Person p = (Person)obj;
        return p.toString().equals(toString());
    }

    @Override
    public int hashCode(){
        return toString().hashCode();
    }

    @Override
    public String toString(){
        return String.format("Health: %03d, Strength: %03d, Food: %03d, Nation: %02d", health, strength, food, nation);
    }
}

一些关键点:

  • inhabs.remove(p);无法正常工作 我想要的方式。
  • 它在第一次迭代中起作用,但在第二次迭代中它只返回false
  • 由于行Person.equals(Object obj),ArrayList对if(obj == this){return true;}的第一次迭代始终返回true。
  • 在第二次迭代中,它甚至从未开始比较对象(?!?)。
  • ArrayList不为空。

我知道这是一个非常具体的问题,但我找不到任何解决ArrayList问题的事情,甚至没有查看其中的元素。

编辑:更多代码。可能与问题无关,但无论如何我都会发布它,以供上下文使用。

class Grid{        
    Cell[][] grid;

    public Grid(Cell[][] in){
        grid = in; //has some cells with people in it.
    }

    //simply iterates over all cells
    public void tick(){
        for(int y = 0; y<grid.length; y++){
            for(int x = 0; x<grid[y].length; x++){
                grid[y][x].tick();
            }
        }
}


class Cell
{
    Grid grid;

    public Cell(/*some constants constants*/ Grid g, ArrayList<Person> inh){
        grid = g;
        if(inh == null){
            inhabs = new ArrayList<Person>();
        }else{
            inhabs = inh;
        }
    }

    //tells every person to make a step
    public void tick(){
        for(Person p : inhabs.toArray(new Person[inhabs.size()])){
            p.tick();
        }
    }

    //and all the other methods from above, of course
}


class Person extends Object
{
    Cell cell;

    public Person(Cell c, int h, int s, int f, int n){
        cell = c;
        health = h;
        strength = s;
        food = f;
        nation = n;
    }

    public void tick(){
        //for testing, later more options
        cell.moveMe(this);
    }

    //and all the other methods from above, of course
}

2 个答案:

答案 0 :(得分:0)

这是不可复制的,这是一个小逻辑测试:

public static void main(String args[]) {
    Person p1 = new Person(10, 2, 2, 1);
    Person p2 = new Person(10, 2, 2, 2);
    Person p3 = new Person(10, 2, 2, 3);

    List<Person> list = new ArrayList<Person>();
    list.add(p1);
    list.add(p2);
    list.add(p3);

    System.out.println(list.remove(p2)); //true
    System.out.println(list.remove(p2)); //false
    System.out.println(list.remove( new Person(10, 2, 2, 3))); //true
}

我的猜测是你没有使用正确的Person,你要么构造一个新实例而不正确地给出每个变量。 (请注意,您没有在此处提供构造函数,值为final,这无法正常工作...)

我已经阅读了你的代码。你的问题很简单。

tick Cell tick Person Cell Person Cell。在那里,您使用Cell.moveMe(Person p);从当前Cell.inhabs移动Person。您确实在新Cell中移动实例并将其从当前实例中删除。 但是,因为您同时引用了所有实例,所以public void tick(){ //for testing cell.moveMe(this); } 从未被指示移动cell ...所以当您致电时:

cell

public Cell moveMe(Person p){ Cell northOfHere = null; try{ northOfHere = grid.grid[y-1][x]; northOfHere.add(p); }catch(ArrayIndexOutOfBoundsException ex){ System.out.println("fell from edge");/*person falls from the edge of the world*/ } System.out.format("Remove from %s person %s%n", this, p); System.out.println("removed: " + inhabs.remove(p)); return northOfHere; } 仍然是最初的位置......但是public void tick(){ //for testing cell = cell.moveMe(this); } 没有抓住那个人,所以它无法删除收到的实例。

一个简单的修正就是将你移动到的单元格返回:

cell

并更新该单元格:

null

我同意将function fadeInOut(element) { $(element).fadeIn("slow", function() { $(this).fadeOut("slow"); }) } function displayStepWords() { $('.stepWord').each(function(i) { var me = $(this); setTimeout( function(){fadeInOut(me);}, 1000 * i ); }) } displayStepWords();保留在<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="stepWord">BYE</div> <div class="stepWord">BY</div> <div class="stepWord">B</div> <div class="stepWord">BY</div> <div class="stepWord">BYE</div>,当他感觉不在地图时,因为它仍在任何单元格之外。

答案 1 :(得分:0)

Andy Turner指出,您需要修复equals()方法。在Person班级中,equals()必须准确无误。

hashCode()equals()之间有一个contract:如果一个对象等于另一个,则他们的hashCode()必须相同。因此,最简单的方法是在equals()上搭载toString()

class Person // automatically extends Object
{

    // ...
    @Override

    public boolean equals(Object obj) {
        return (obj instanceof Person) && // instanceof is null-safe
            this.toString().equals((Person) obj).toString();
    }
}

老实说,我不喜欢 编写 equals()hashCode()方法,除非绝对必要。它们很麻烦且容易出错。在这种情况下,它看起来并不绝对必要。有几种选择:

  • 使用IDE生成它们
  • 使用apache EqualsBuilderHashCodeBuilderHere就是一个很好的例子。

使用HashCodeBuilder,您可以编写如下代码:

@Override
public int hashCode() {
   return new HashCodeBuilder()
      .append(this.health)
      .append(this.strength)
      ...
      .toHashCode();
}

使用EqualsBuilder,您可以编写如下代码:

@Override
public boolean equals(Object obj) {
      if (obj instanceof Person == false)
      {
        return false;
      }
      if (this == obj)
      {
         return true;
      }

      Person that = (Person) obj;
      return new EqualsBuilder()
        .append(this.health, that.health)
        .append(this.strength, that.strength)
        ...
        .isEquals();
}
相关问题