【问题标题】:IndexOutOfBoundsException problemsIndexOutOfBoundsException 问题
【发布时间】:2013-04-10 20:58:25
【问题描述】:

我希望有人可以帮助我解决 IndexOutOfBoundsException 错误。

我可以设置一个区域内的单位数量,我可以设置该区域的所有者,但是防御功能会导致问题。

追踪:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at stackOverflow.Territory.calculateLoses(Territory.java:136)
at stackOverflow.Territory.defend(Territory.java:95)
at stackOverflow.Territory.defend(Territory.java:40)
at stackOverflow.Territory.main(Territory.java:155)



import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public enum Territory {

// Europe
GREATBRITAIN("Great Britain"), ICELAND("Iceland");

private final String name;
private int numberOfUnits;
private Player player;
private int ad = 0, dd = 0;

private Territory(String name) {
    this.name = name;
    this.numberOfUnits = 0;
    this.player = null;
}

public void setOwner(Player p) {
    this.player = p;
}

public Player getOwner() {
    return this.player;
}

public int getNumberUnits() {
    return this.numberOfUnits;
}

public void setNumberUnits(int units) {
    this.numberOfUnits = units;
}

public boolean defend(Territory attacker) throws Exception {
    return defend(attacker, attacker.numberOfUnits - 1);
}

public boolean defend(Territory attacker, int attackingUnits)
        throws Exception {
    if (attackingUnits > (attacker.getNumberUnits() - 1)) {
        throw new Exception("Invalid number of units");
    }

    attacker.setNumberUnits(attacker.numberOfUnits - attackingUnits);
    Player defender = this.player;
    this.player = null;
    int defendingUnits = this.numberOfUnits;
    this.numberOfUnits = 0;

    if (this.numberOfUnits >= 3 && defendingUnits >= 2) {
        ad = 3;
        dd = 2;
    }
    if (this.numberOfUnits >= 3 && defendingUnits == 1) {
        ad = 3;
        dd = 1;
    }
    if (this.numberOfUnits == 2 && defendingUnits >= 2) {
        ad = 2;
        dd = 2;
    }
    if (this.numberOfUnits == 2 && defendingUnits == 1) {
        ad = 2;
        dd = 1;
    }
    if (this.numberOfUnits == 1 && defendingUnits >= 2) {
        ad = 1;
        dd = 2;
    }
    if (this.numberOfUnits == 1 && defendingUnits == 1) {
        ad = 1;
        dd = 1;
    }
    if (this.name == "Great Britan" || this.name == "Central America"
            || this.name == "Argentina" || this.name == "Egypt"
            || this.name == "Western Australia" || this.name == "India") {
        dd++;
    }

    List<Die> attackerDice = createDice(ad);
    List<Die> defenderDice = createDice(dd);
    System.out.printf("Attacker: %d \tDefender: %d\n", attackingUnits,
            defendingUnits);
    while (attackingUnits > 0 && defendingUnits > 0) {
        roll(attackerDice);
        System.out.println(attackerDice);
        roll(defenderDice);
        System.out.println(defenderDice);

        attackingUnits -= calculateLoses(attackerDice, defenderDice, false);
        defendingUnits -= calculateLoses(defenderDice, attackerDice, true);

        System.out.printf("Attacker: %d \tDefender: %d\n", attackingUnits,
                defendingUnits);
    }

    if (defendingUnits > 0) {
        this.player = defender;
        this.numberOfUnits = defendingUnits;
        return true;
    } else if (attackingUnits > 0) {
        this.numberOfUnits = attackingUnits;
        this.player = attacker.player;
        return false;
    } else {
        // No one owns the territory as all units died
        return false;
    }
}

private List<Die> createDice(int number) {
    List<Die> dice = new ArrayList<Die>();
    for (int i = 0; i < number; i++) {
        dice.add(new Die());
    }
    roll(dice);
    return dice;
}

private void roll(List<Die> dice) {
    for (Die d : dice) {
        d.roll();
    }
    Collections.sort(dice);
}

private int calculateLoses(List<Die> diceOne, List<Die> diceTwo,
        boolean defender) {
    int number = 0;
    for (int i = 0; i < 2; i++) {
        int comparison = diceOne.get(i).compareTo(diceTwo.get(i));
        if (comparison > 0 || (!defender && comparison == 0)) {
            number++;
        }
    }
    return number;
}

String units()
{
    return "" + numberOfUnits;
}

public static void main(String[] args) throws Exception
{
    Territory.GREATBRITAIN.setNumberUnits(5);
    System.out.println(Territory.GREATBRITAIN.getNumberUnits());
    Territory.ICELAND.setNumberUnits(5);
    System.out.println(Territory.ICELAND.getNumberUnits());
    Territory.GREATBRITAIN.defend(Territory.ICELAND);
}
}

【问题讨论】:

  • 在哪里?哪条线?顺便说一句,this.name == "Great Britan" 不对。使用.euqals 比较字符串。
  • 除了随机之外,使用IllegalArgumentException 而不是Exception 来处理代码中的无效输入。这也将使您不必为每种方法都说throws Exception
  • 我觉得和diceOne和DiceTwo有关
  • 另外,使用.equals()而不是==来比较Java中的字符串。

标签: java arraylist indexoutofboundsexception


【解决方案1】:

看起来addd 或两者都是0。

这是有道理的,鉴于此代码:

this.numberOfUnits = 0;

// Lots of these, all requiring numberOfUnits to be greater than 0
if (this.numberOfUnits >= 3 && ...)
{
    ad = ...;
    dd = ...;
}

当您刚刚将 numberOfUnits 设置为 0 时,您如何期望进入任何 if 块?

这只是代码中的一个问题。其他人指出了风格或正确性的其他方面。我不会尝试在此处修复您的所有代码 - 但您应该分析如何自己诊断出这个问题。例如,您是否尝试过在调试器中单步执行代码?

【讨论】:

  • 另外值得一提的是==的用法如果他想比较strings对象也不好。
  • @MarounMaroun:在代码的其余部分留下了一般注释。列出所有错误的地方会花费很长时间。
【解决方案2】:

这段代码是错误的:

if (this.name == "Great Britan" || this.name == "Central America"
        || this.name == "Argentina" || this.name == "Egypt"
        || this.name == "Western Australia" || this.name == "India") {
    dd++;
}

使用this.name.equals("Great Britain") 测试字符串是否包含相同的字符,而不是测试它们是否存储在内存中的相同位置。

此外,您的许多单独的 if 语句看起来像是不好的做法;使用else 或其他东西来检查您是否至少击中了一个案例 - 在设置this.numberOfUnits = 0; 后,您显然没有遇到任何this.numberOfUnits &gt;= [stuff] 案例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-19
    • 1970-01-01
    • 2019-06-01
    • 2013-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多