1

我正在构建一个只使用 array的经典 Nim 游戏,我在测试后发现有一个错误。如果我成功创建了一个播放器,我会为数组分配一个新对象。但是,当删除数组中的播放器时,我会使用非空对象过滤数组,因为我还有其他函数,例如editplayer,displayplayer来迭代整个数组而没有NullPointerException.

并且有可能发生这种情况:addplayerremoveplayeraddplayer。这意味着IndexOutOfBound当我尝试将新对象分配给已经充满非空对象的数组时,我总是会得到。

我已经搜索了所有我能找到的信息,但是没有关于这个的讨论。有什么办法可以同时避免NullPointerException两者IndexOutOfBound

这是相关代码Nimsys

public class Nimsys {

public static void addPlayer(String [] name) {
    if (name != null && name.length == 3) {
        for (int i = 0; i < NimPlayer.getCounter(); i++) {
            String userCheck = NimPlayer.getPlayer()[i].getUserName();
            if (userCheck.contains(name[0])) {
                System.out.println("The player already exists.\n");// Test if player has been created
                return;
            }
        }
        NimPlayer.createPlayer(name[0], name[1], name[2]);
        System.out.println("The player has been created.");
        return;
    } 
    System.out.println("Not Valid! Please enter again!");   
}

public static void searchAndRemovePlayer(String user) {
    NimPlayer [] playerList = NimPlayer.getPlayer();
    for (int i = 0; i < playerList.length; i++) {
        String userName =playerList[i].getUserName().trim();
        if (userName.equals(user)) {
            playerList[i] = null;
            System.out.println("Remove successfully!");
            NimPlayer.setPlayerList(playerList);
            return;
        }
    }
    System.out.println("The player does not exist.\n");

}
}

这是NimPlayer课堂的一部分:

public class NimPlayer {
private String userName;
private String familyName;
private String givenName;
private int score;
private int gamePlayed;

private static int counter;
private static final int SIZE = 10;
private static NimPlayer[] playerList = new NimPlayer[SIZE]; // set an array here


//define NimPlayer data type
public NimPlayer(String userName, String surName, String givenName) {
    this.userName = userName;
    this.familyName = surName;
    this.givenName = givenName;

}
// create new data using NimPlayer data type
public static void createPlayer(String userName, String familyName, String givenName) {
    if (counter < SIZE) {
        playerList[counter++] = new NimPlayer(userName, familyName, givenName);
    } else {
        System.out.println("Cannot add more players.");
    }
}
public static int getCounter() {
    return counter;
}
public static NimPlayer [] getPlayer() {      
    return playerList;
}
public static void setPlayerList(NimPlayer [] newplayerList) {
    playerList = Arrays.stream(newplayerList).filter(Objects::nonNull).toArray(NimPlayer[]::new);
    counter = playerList.length;  //update the counter
}
    //setters and getters of the other variables
}
4

2 回答 2

1
  1. 我建议您阅读NullPointerExceptionArrayIndexOutOfBoundsException的文档,而不是解释这些异常。当它们发生时处理这些异常并不是什么大问题。但是,最重要的是要防止它们,即您应该了解根本原因并对其进行处理。我们都知道,“预防胜于治疗”。.
  2. 您应该始终尝试从类中隐藏尽可能多的信息,例如,您已经有一个public static void createPlayerthen,为什么要创建一个public构造函数?你为什么要创建一个只能在类内部使用的publicgetter ?counterNimPlayer
  3. 而不是从外部公开playerList要设置的,您应该删除它的public设置器并创建public static void removePlayer类似于public static void createPlayer.

附带说明(因为它不会影响程序的执行),标识符的名称应该是不言自明的,例如,您的getPlayer方法应该被命名为getPlayerList它返回的playerList,而不是单个玩家。

下面给出了包含这些注释的代码:

import java.util.Arrays;
import java.util.Objects;

class NimPlayer {
    private String userName;
    private String familyName;
    private String givenName;
    private int score;
    private int gamePlayed;

    private static int counter;
    private static final int SIZE = 10;
    private static NimPlayer[] playerList = new NimPlayer[SIZE];

    private NimPlayer(String userName, String surName, String givenName) {
        this.userName = userName;
        this.familyName = surName;
        this.givenName = givenName;
    }

    public static void createPlayer(String userName, String familyName, String givenName) {
        if (counter < SIZE) {
            playerList[counter++] = new NimPlayer(userName, familyName, givenName);
        } else {
            System.out.println("Cannot add more players.");
        }
    }

    public static void removePlayer(NimPlayer player) {
        int i;
        for (i = 0; i < playerList.length; i++) {
            if (playerList[i] != null && playerList[i].getUserName().equals(player.getUserName())) {
                break;
            }
        }
        for (int j = i; j < playerList.length - 1; j++) {
            playerList[j] = playerList[j + 1];
        }
        counter--;
    }

    public static NimPlayer[] getPlayerList() {
        return Arrays.stream(playerList).filter(Objects::nonNull).toArray(NimPlayer[]::new);
    }

    public String getUserName() {
        return userName;
    }

    public String getFamilyName() {
        return familyName;
    }

    public String getGivenName() {
        return givenName;
    }

    @Override
    public String toString() {
        return userName + " " + familyName + " " + givenName;
    }
}

class NimSys {

    public static void addPlayer(String[] name) {
        if (name != null && name.length == 3) {
            NimPlayer[] playerList = NimPlayer.getPlayerList();
            for (int i = 0; i < playerList.length; i++) {
                String userCheck = playerList[i].getUserName();
                if (userCheck.contains(name[0])) {
                    System.out.println("The player, " + name[0] + " already exists.\n");
                    return;
                }
            }
            NimPlayer.createPlayer(name[0], name[1], name[2]);
            System.out.println("The player, " + name[0] + "  has been created.");
            return;
        }
        System.out.println("Not Valid! Please enter again!");
    }

    public static void searchAndRemovePlayer(String user) {
        NimPlayer[] playerList = NimPlayer.getPlayerList();
        for (int i = 0; i < playerList.length; i++) {
            String userName = playerList[i].getUserName().trim();
            if (userName.equals(user)) {
                NimPlayer.removePlayer(playerList[i]);
                System.out.println("The player, " + user + " removed successfully!");
                return;
            }
        }
        System.out.println("The player, " + user + "  does not exist.\n");
    }

    public static void displayPlayerList() {
        NimPlayer[] playerList = NimPlayer.getPlayerList();
        StringBuilder sb = new StringBuilder();
        for (NimPlayer player : playerList) {
            sb.append(player.getUserName()).append(" ").append(player.getFamilyName()).append(" ")
                    .append(player.getGivenName()).append(System.lineSeparator());
        }
        System.out.println(sb);
    }
}

public class Main {
    public static void main(String[] args) {

        NimSys.addPlayer(new String[] { "Harry", "Potter", "Harry" });
        NimSys.displayPlayerList();

        NimSys.searchAndRemovePlayer("Harry");
        NimSys.displayPlayerList();

        NimSys.addPlayer(new String[] { "Manny", "Richard", "Canty" });
        NimSys.displayPlayerList();

        NimSys.addPlayer(new String[] { "Arvind", "Kumar", "Avinash" });
        NimSys.displayPlayerList();

        NimSys.searchAndRemovePlayer("Manny");
        NimSys.displayPlayerList();

        NimSys.addPlayer(new String[] { "Ken", "Ken", "Thompson" });
        NimSys.displayPlayerList();

        NimSys.searchAndRemovePlayer("Ken");
        NimSys.displayPlayerList();

        NimSys.addPlayer(new String[] { "Ken", "Ken", "Thompson" });
        NimSys.displayPlayerList();

        NimSys.searchAndRemovePlayer("Ken");
        NimSys.displayPlayerList();

        NimSys.addPlayer(new String[] { "Ken", "Ken", "Thompson" });
        NimSys.displayPlayerList();
    }
}

输出:

The player, Harry  has been created.
Harry Potter Harry

The player, Harry removed successfully!

The player, Manny  has been created.
Manny Richard Canty

The player, Arvind  has been created.
Manny Richard Canty
Arvind Kumar Avinash

The player, Manny removed successfully!
Arvind Kumar Avinash

The player, Ken  has been created.
Arvind Kumar Avinash
Ken Ken Thompson

The player, Ken removed successfully!
Arvind Kumar Avinash

The player, Ken  has been created.
Arvind Kumar Avinash
Ken Ken Thompson

The player, Ken removed successfully!
Arvind Kumar Avinash

The player, Ken  has been created.
Arvind Kumar Avinash
Ken Ken Thompson
于 2020-04-29T09:11:33.740 回答
1

回答您的问题:“有什么方法可以同时避免 NullPointerException 和 IndexOutOfBound ?”

是的,您可以通过使用以下两件事来做到这一点。

首先,您可以使用其length属性获取数组的长度。length是数组中元素的数量(包括值为 的元素null)。有了这些信息,您永远不应该越界索引(只要您不编写修改数组长度的并发代码)。

其次,您需要检查从数组中取出的内容是否为空。你可以用 if 语句来做到这一点。

这就是它的样子:

// create an array with 5 elements. 0, 2, and 4 are null. 1 and 3 are not null.
String[] myArray = new String[5];
myArray[1] = "abc ";
myArray[3] = "def";

// myArray.length will be '5'
for (int i = 0; i < myArray.length; i++){
  String value = myArray[i];

  if (value != null) {
    // prints "ABC DEF" and doesn't result in a NullPointer
    System.out.print(value.toUpperCase());
  }
}

所以在你的情况下:

public static void addPlayer(String [] name) {
    if (name != null && name.length == 3) {
        for (int i = 0; i < NimPlayer.getPlayer().length; i++) {
            NimPlayer player = NimPlayer.getPlayer()[i];

            if (player != null && player.getUserName().contains(name[0]))
                System.out.println("The player already exists.\n");
                return;
            }
        }
        NimPlayer.createPlayer(name[0], name[1], name[2]);
        System.out.println("The player has been created.");
        return;
    } 
    System.out.println("Not Valid! Please enter again!");   
}

只是补充一下。在面向对象编程中,您通常希望遵循封装原则——因此您可能希望将 NimSys 中的方法移至 NimPlayer,因为它们对 NimPlayer 中的数据进行操作。

我猜你是 Java 和编程的新手。祝学习顺利!

于 2020-04-29T04:28:32.733 回答