【问题标题】:Java: Optimize two searches and two lists to oneJava:将两个搜索和两个列表优化为一个
【发布时间】:2018-05-07 11:47:13
【问题描述】:

我正在尝试通过消除重复搜索来优化我的程序,或者只是通过通常在整个程序中进行优化,我遇到了一种方法,在这种方法中我找不到任何“更好”的解决方案。很想知道是否有人可以指出我改进它的方向。

首先是我正在尝试优化的代码:

public Player spaceBattle(Player player1, Player player2) {
    ArrayList<Ship> listOfShipsPlayer1 = this.getShipsOfPlayer(player1);
    ArrayList<Ship> listOfShipsPlayer2 = this.getShipsOfPlayer(player2);

    Random random = new Random();

    int player1hits = 0, player2hits = 0, rolledDie;

    for (Ship aShip : listOfShipsPlayer1) {
        rolledDie = random.nextInt(10) + 1;
        if (rolledDie >= aShip.getShipType().getCombatValue()) {
            player1hits += 1;
        }
    }

    for (Ship aShip : listOfShipsPlayer2) {
        rolledDie = random.nextInt(10) + 1;
        if (rolledDie >= aShip.getShipType().getCombatValue()) {
            player2hits += 1;
        }
    }

    for (int i = 0; i < player1hits; ++i) {
        if (this.getShipsOfPlayer(player2).size() > 0) {
            this.listOfShips.remove(listOfShipsPlayer2.get(i));
        } else {
            break;
        }
    }

    for (int i = 0; i < player2hits; ++i) {
        if (this.getShipsOfPlayer(player1).size() > 0) {
            this.listOfShips.remove(listOfShipsPlayer1.get(i));
        } else {
            break;
        }
    }

正如您在此处看到的那样,我运行了两次相同的算法,以检查第一个 Player1,然后是 Player2,并添加更新它们各自的命中。然后对于每个玩家的命中数,然后我移除一艘船。 我想知道是否可以更改这段代码以使每个播放器都没有重复的代码,但它可以自动先通过播放器1,然后在一个循环中通过播放器2。

期待您的来信

【问题讨论】:

  • 为每个算法添加一个方法是否被视为优化?
  • 我投票结束这个问题,因为这是一个寻求改进的有效解决方案,这应该发布在Code Review

标签: java algorithm optimization


【解决方案1】:

你可以只创建方法。

private int hitShips(List<Ship> ships) {
    int result = 0;
    for (Ship ship : ships) {
        rolledDie = random.nextInt(10) + 1;
        if (rolledDie >= ship.getShipType().getCombatValue()) {
            result++;
        }
    }
    return result;
}

这让你的代码

int player1hits = hitShips(listOfShipsPlayer1);
int player2hits = hitShips(listOfShipsPlayer2);

和类似的从列表中删除船只。

void removeShips(List<Ship> ships, int remove) {
    int removeCount = Math.max(ships.size(), remove);
    Iterator<Ship> it = ships.iterator();
    for (int i = 0; i < removeCount; i++) {
        it.remove();
    }
}

removeShips(getShipsOfPlayer(player2), player1hits);
removeShips(getShipsOfPlayer(player1), player2hits);

我不知道你为什么总是从列表的顶部删除舰船,因为战斗值似乎是一个东西,但这只是一个旁注。

我不会这么称它为“优化”,但删除重复代码总是好的。

【讨论】:

    【解决方案2】:

    您可以将 removeShips 优化为:

    void removeShips(List<Ship> ships, int numHits) {
      int numToRemove = Math.min(ships.size(), numHits);
      if (numToRemove > 0) {
        ships.subList(0, numToRemove).clear();
      }
    }
    

    此方法调用将只导致一次System.arraycopy 调用,这会将所有剩余元素向左移动。

    https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#subList-int-int-

    【讨论】:

      猜你喜欢
      • 2012-10-24
      • 1970-01-01
      • 1970-01-01
      • 2010-09-27
      • 2021-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多