2

这是一个多部分的问题。

限制:

  • 不能使用.clone(), 或Collections, 或System.
  • 不能更改为不同的对象类型(我的意思是我不能更改ArrayList为 aList或不更改)。

我想我的问题可能是我还没有完全掌握如何抛出异常。不过不确定。

这是我坚持的任务的一部分。

如果可能,将鱼 f 添加到鱼列表中。

首先检查鱼所在位置的景观是否等于 ROCK。如果是,则鱼不会添加到列表中。相反,抛出一个 IllegalFishPositionException,传递 IllegalFishPositionException.FISH_OVER_ROCK给构造函数。

接下来检查与参数位于同一位置的另一条鱼(与参数不同)。如果找到一个,则不会将鱼添加到列表中。而是抛出一个 IllegalFishPositionException,传递IllegalFishPositionException.TWO_FISH_IN_ONE_PLACE给构造函数。

否则,将参数添加到鱼列表。

public void addFish(Fish f) {
    ArrayList <Fish> addFish = new ArrayList <Fish>( fish );

    if ( landscape[ f.getRow() ][ f.getCol() ] == ROCK ) {
        throw new IllegalFishPositionException(
                IllegalFishPositionException.FISH_OVER_ROCK );
    }
    for ( Fish f1 : addFish ) {
        if ( ( f1.getRow() == f.getRow() && 
                f1.getCol() == f.getCol() ) || f1 == f ) {
            throw new IllegalFishPositionException(
                    IllegalFishPositionException.TWO_FISH_IN_ONE_PLACE );
        }
    }
    for ( Fish f2 : addFish ) {
        if ( ( f2.getRow() != f.getRow() && 
                f2.getCol() != f.getCol() ) && 
                landscape[ f.getRow() ][ f.getCol() ] != ROCK ) {
            fish.add( f );
        }
    }

}

这是对我来说似乎合乎逻辑的第二种方法,但在测试中失败了。

/* Checks the specified location to see if it has a rock, fish, or plant 
 * in it. If so, returns false; if it is just water, returns true. */
public boolean isSpaceAvailable(int r, int c) {
    if ( landscape[r][c] == ROCK ) {
        return false;
    }
    for ( Fish f : fish ) {
        if ( ( f.getRow() == r ) && ( f.getCol() == c ) ) {
            return false;
        }
    }
    for ( Plant p : plants ) {
        if ( ( p.getRow() == r ) && ( p.getCol() == c ) ) {
            return false;
        }
    }
    return true;
}

我还有其他几个依赖于 addFish 的方法,所以如果我能做对,它就会产生级联效应。

这是我需要为 isSpaceAvailable 方法通过的 JUnit 测试。

@Test
public void testIsSpaceAvailable() {
    Model m = new Model(10,10,0,0,0);
    Fish f = new Fish(1, 7, 100, Fish.UP);
    Plant p = new Plant(2, 8, 100);
    m.addFish(f);
    m.addPlant(p);
    assertFalse(m.isSpaceAvailable(1, 7));
    assertFalse(m.isSpaceAvailable(2, 8));
    assertFalse(m.isSpaceAvailable(0, 0));
    for (int i = 1; i < 9; i++) {
        for (int j = 1; j < 9; j++) {
            if ((i != 1 || j != 7) && (i != 2  || j != 8)) {
                assertTrue(m.isSpaceAvailable(i, j));
            }
        }
    }
}

如果你们需要查看它,这里是该项目的 JavaDoc。 http://www.cs.umd.edu/class/spring2013/cmsc131-23/Projects/P7/doc/index.html

我已经盯着这个看了一段时间,我完全被卡住了。

4

2 回答 2

0

addFish状态不好。删除 local ArrayList,如果您担心线程安全/并发性,请使用锁定策略或同步方法。最后的循环是错误的和多余的,当你点击它时,你已经满足了添加鱼的条件。你能在植物所在的地方添加一条鱼吗?

public void addFish(Fish f) {

    if ( landscape[ f.getRow() ][ f.getCol() ] == ROCK ) {
        throw new IllegalFishPositionException(
                IllegalFishPositionException.FISH_OVER_ROCK );
    }

    for ( Fish f1 : this.fish ) {
        // is Fish.equals implemented if so use that.
        if ( f1 == f){

           // fish already in list nothing to do
           // usually bad practice to have return in middle of method
           return; 

        } else if ( ( f1.getRow() == f.getRow() && 
                f1.getCol() == f.getCol() )) {
            throw new IllegalFishPositionException(
                    IllegalFishPositionException.TWO_FISH_IN_ONE_PLACE );
        }
    }

   fish.add( f );

}
于 2013-05-10T01:55:44.727 回答
0

你有一个冗余的第二个循环addFish(),如果没有鱼可以开始,它将多次添加鱼/或永远不会添加鱼。

错误的:

for ( Fish f2 : addFish ) {
    if ( ( f2.getRow() != f.getRow() && 
            f2.getCol() != f.getCol() ) && 
            landscape[ f.getRow() ][ f.getCol() ] != ROCK ) {
        fish.add( f );    // adds F repeatedly!
    }
}

正确代码:

public void addFish (Fish f) {
    // we don't need to copy the 'fish' list -- but if we did, we'd call it 'copyFish' not 'addFish'.
    /* List<Fish> copyFish = new ArrayList<Fish>( fish); */

    if (landscape[ f.getRow()][ f.getCol()] == ROCK) {
        throw new IllegalFishPositionException( IllegalFishPositionException.FISH_OVER_ROCK);
    }
    for (Fish exist : fish) {
        if ((exist.getRow() == f.getRow() && exist.getCol() == f.getCol()) {
            throw new IllegalFishPositionException(
                    IllegalFishPositionException.TWO_FISH_IN_ONE_PLACE);
        }
    }
    // All OK;     clear water, no rock or other fish there.
    //    -- add the fish.
    fish.add( f);
    landscape[ f.getRow()][ f.getCol()] = FISH;
}

另外,清理你的代码。使其紧凑,有文化且可读。

您需要编写有意义的简洁代码,而不是冗长的口头和空白填充,但没有。

我个人的做法是在列表/设置/映射/集合字段(不是参数)后面加上“列表”或其他任何东西,例如“鱼列表”。这将它们与作为参数传递的列表区分开来,这是一个常见的用例。

于 2013-05-10T01:59:36.260 回答