Java 鱼塘模拟:作业,我哪里做错了?

Java 鱼塘模拟:作业,我哪里做错了?,java,Java,这是一个多部分的问题 限制: 无法使用.clone(),或集合,或系统 无法更改为其他对象类型(我的意思是我无法将ArrayList更改为列表或其他类型) 我想我的问题可能是我还没有完全掌握如何抛出异常。 不过我不确定 这是我一直坚持的作业的一部分 如果可能,将鱼f添加到鱼列表中 首先检查鱼所在位置的景观是否与岩石相同。 如果是,则不会将鱼添加到列表中。相反,抛出一个 IllegalFishPositionException,传递 IllegalFishPositionException.在

这是一个多部分的问题

限制:

  • 无法使用
    .clone()
    ,或
    集合
    ,或
    系统
  • 无法更改为其他对象类型(我的意思是我无法将
    ArrayList
    更改为
    列表
    或其他类型)
我想我的问题可能是我还没有完全掌握如何抛出异常。 不过我不确定

这是我一直坚持的作业的一部分

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

首先检查鱼所在位置的景观是否与岩石相同。 如果是,则不会将鱼添加到列表中。相反,抛出一个 IllegalFishPositionException,传递
IllegalFishPositionException.在岩石上钓鱼
给构造函数。 下一步检查中的另一条鱼(与参数不同) 与参数的位置相同。如果找到了一条,那么鱼就死了 没有添加到列表中。而是抛出一个非法的异常, 正在将非法FishPositionException.TWO_FISH_ONE_PLACE传递到 构造器。 否则,将参数添加到鱼列表中

我还有一些其他方法依赖于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));
            }
        }
    }
}
@测试
public void testIsSpaceAvailable(){
模型m=新模型(10,10,0,0);
鱼f=新鱼(1,7100,鱼向上);
工厂p=新工厂(2,8100);
m、 addFish(f);
m、 添加植物(p);
assertFalse(m.isSpaceAvailable(1,7));
assertFalse(m.isSpaceAvailable(2,8));
assertFalse(m.isSpaceAvailable(0,0));
对于(int i=1;i<9;i++){
对于(int j=1;j<9;j++){
如果((i!=1 | j!=7)和&(i!=2 | j!=8)){
资产真实(m.isSpaceAvailable(i,j));
}
}
}
}
这里是项目的JavaDoc,如果你们需要查看的话。


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

addFish
的状态很糟糕。如果担心线程安全性/并发性,请使用锁定策略或同步该方法,删除本地
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 );

}

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;
}
public void addFish(鱼f){
//我们不需要复制“鱼”列表,但如果复制了,我们会称之为“复制鱼”而不是“addFish”。
/*List copyFish=新阵列列表(fish)*/
如果(横向[f.getRow()][f.getCol()]==岩石){
抛出新的IllegalFishPositionException(IllegalFishPositionException.FISH_OVER_ROCK);
}
对于(鱼存在:鱼){
if((exist.getRow()==f.getRow()&&exist.getCol()==f.getCol()){
抛出新的IllegalFishPositionException异常(
非法捕鱼(例外。两条鱼在一个地方);
}
}
//一切正常;那里有清澈的水,没有岩石或其他鱼类。
//——加鱼。
鱼。加入(f);
景观[f.getRow()][f.getCol()]=鱼;
}
另外,清理你的代码,使其紧凑、可读

您需要编写有意义的简明代码,而不是冗长的文字和空白,否则会造成混乱


我个人的做法是为列表/设置/映射/集合字段(非参数)添加后缀这是一个常见的用例。你说你错了,你说你失败了,但是你给了我们不完整的代码,不告诉我们什么是错的。这里有一些人认为一个完整的例子是必要的,但更重要的是,这是必须的。你告诉我们什么是错误的。我们甚至不能运行它来发现我们自己。基本上,你所做的是给我们一堆代码,让我们看看是否可以找到它的错误——我们甚至没有得到任何证据表明问题出在这段代码中。我已经根据提供的测试测试了我的其他方法,addFish遇到的任何时候调用hod时,测试失败。如果需要,我可以发布java文件。这对我来说很有效。非常感谢!!我有一个请求:为了更好地理解异常,所以每当抛出异常时,它下面的代码都不会执行,对吗?还有,为什么分离f=f1条件会让一切正常?我有很多东西要学习,希望有人能提供一些澄清。@KatoPlato异常的行为类似于返回语句,只是它没有被调用方法“捕获”,而是被包装的catch块“捕获”。唯一要做的是忽略鱼,如果它在您的条件下已经在列表中
f=f1
,则它是多余的如果为true,则or条件的另一面将为true。在这种情况下抛出异常没有多大意义。还值得努力理解
try
catch
最后它们非常有用,因此您将经常遇到它们。我想改进我的“风格”是否有一个我可以参考的网站可以提供帮助?Java风格的惯例还是更一般的
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;
}