将 Two 类 添加到 ArrayList<Class> 会用两个重复项填充 arraylist
Adding Two Classes to ArrayList<Class> fills the arraylist with two duplicates
我在制作 Spigot 插件时制作了一个名为 ArrayList<Arena>
的 ArrayList。
public static ArrayList<Arena> all = new ArrayList<Arena>();
现在我有了 class,这是实例化步骤:
public Arena(String name, int min, int max) {
Arena.name = name;
Arena.layout = "default";
Arena.customName = CManager.getPlugin().getArenaConfig().getString("arenas." + name + ".custom-name");
ArenaManager.addToArenaList(this);
ArenaManager.arenaNames.add(Arena.name);
Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.LIGHT_PURPLE + "[" + plugin.getPdfFile().getName()
+ "]" + ChatColor.GREEN + " [#] (Instanciated arena " + Arena.name + ")");
Arena.min = min;
Arena.max = max;
Arena.world = Bukkit.getWorld(Arena.name);
waiting = true;
starting = false;
game = false;
finished = false;
}
我对这段看似简单的代码有疑问。
public static void addToArenaList(Arena a) {
all.add(a);
checkArena(a);
}
public static void checkArena(final Arena a) {
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
public void run() {
if (!(all.contains(a))) {
Bukkit.getServer().getConsoleSender().sendMessage(
ChatColor.LIGHT_PURPLE + "[" + plugin.getPdfFile().getName() + "]" + ChatColor.RED
+ " [E] (Error while adding arena " + a.getArenaName() + "to list)");
} else {
Boolean found = false;
for (Arena f : all) {
if (f.getArenaName().equals(a.getArenaName())) {
if (found == true) {
Bukkit.getServer().getConsoleSender()
.sendMessage(ChatColor.LIGHT_PURPLE + "[" + plugin.getPdfFile().getName() + "]"
+ ChatColor.RED + " [E] (Duplicate found with arena "
+ a.getArenaName());
continue;
}
found = true;
}
}
if (found == false) {
Bukkit.getServer().getConsoleSender()
.sendMessage(ChatColor.LIGHT_PURPLE + "[" + plugin.getPdfFile().getName() + "]"
+ ChatColor.RED + " [E] (Error while adding arena " + a.getArenaName()
+ "to list)");
}
}
}
}, 10L);
}
但出于某种原因,我得到了最后一个竞技场的副本,这也是该过程的第一阶段
public void onEnable() {
Methods.sendColoredMessage(this, ChatColor.LIGHT_PURPLE, ("Registering Commands...."), ChatColor.YELLOW);
registerCommands();
Methods.sendColoredMessage(this, ChatColor.LIGHT_PURPLE, ("Registering Events...."), ChatColor.YELLOW);
registerEvents();
Methods.sendColoredMessage(this, ChatColor.LIGHT_PURPLE, ("Registering Config...."), ChatColor.YELLOW);
createFiles();
Methods.sendColoredMessage(this, ChatColor.LIGHT_PURPLE, ("Attempting to load arenas...."), ChatColor.GOLD);
ArenaManager.all.clear();
ArenaManager.arenaNames.clear();
ArenaManager.createArenas();
Methods.sendColoredMessage(this, ChatColor.AQUA,
(pdfFile.getName() + " has been enabled! (V." + pdfFile.getVersion() + ")"), ChatColor.GREEN);
}
public static void createArenas() {
if (plugin.getArenaConfig().getConfigurationSection("arenas") != null) {
int count = 0;
ArrayList<String> listed = new ArrayList<String>();
for (String arena : plugin.getArenaConfig().getStringList("enabled")) {
count++;
Bukkit.getServer().getConsoleSender()
.sendMessage(ChatColor.LIGHT_PURPLE + "[" + plugin.getPdfFile().getName() + "]"
+ ChatColor.GREEN + " [" + count + "] (Loading arena " + arena + ")");
int min = plugin.getArenaConfig().getInt("arenas." + arena + ".min");
int max = plugin.getArenaConfig().getInt("arenas." + arena + ".max");
new Arena(arena, min, max);
}
Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.LIGHT_PURPLE + "["
+ plugin.getPdfFile().getName() + "]" + ChatColor.GREEN + " [A] Loaded arenas are listed below:");
for (Arena a : all) {
if (listed.contains(a.getArenaName())) {
continue;
}
Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.LIGHT_PURPLE + "["
+ plugin.getPdfFile().getName() + "]" + ChatColor.GREEN + " [A] - " + a.getArenaName());
listed.add(a.getArenaName());
}
} else {
Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.LIGHT_PURPLE + "["
+ plugin.getPdfFile().getName() + "]" + ChatColor.RED + " [E] No arenas have been found!");
}
}
因此,如果我有 4 个竞技场,最后一个叫做 EndArena,在我的数组中,我最终会得到 4 个元素都具有相同的竞技场 class EndArena。我什么都试过了,我通常不喜欢寻求帮助(我更喜欢自己学东西)但这让我很烦恼,所以我不得不提交它。
还有我的竞技场YAML文件
出现这种情况是因为您没有正确使用对象。
据我了解您的代码,您想要创建某种 Arena,为该 Arena 分配一些值,然后将其添加到某个 ArenaManager。这可以。为此,您需要使用实例变量,这样每个创建的 Arena 都会有自己的名称。该特定实例的唯一性。
您在这里使用的是静态字段 - 静态在程序中的所有对象中都是相同的,这不是您在这里需要的(如果您需要竞技场计数器之类的东西,这将是有益的)。
请看一些例子:
想象一下,有一个非常简单和天真的人 class(按照你的方法)。
public class Person {
private static String name;
public Person(String name) {
Person.name = name;
}
}
如果你想做这样的事情:
新人("Adam");
新人("Viktor");
您将以 2 个 person 实例结束(指向)一个静态变量,该变量最终将具有值 Victor。这肯定不是我们在这里需要的东西。为了使其正常工作,您需要使用实例变量:
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
}
现在,在我们的示例代码之后,您将有 2 个人,每个人都有不同的名字。如何访问它们并不重要,真正重要的是它们应该是实例字段——这意味着每个实例在内存中都有单独的块来保存这个值。如果该字段是静态的,它只是意味着所有不同的对象都有一个可能的变量值 - 每次您更改它都会为所有其他对象更改。
总结一下:
您应该使用实例字段而不是静态字段。
在你的构造函数中你有:
Arena.name = 姓名;
Arena.layout = "default";
这两行代码总是会覆盖你 Arena 中的静态字段 class。
在你的 Arena class 你有类似的东西(注意静态关键字):
private static String name;
您需要:
private String name;
所以每个实例都有自己的名字。请阅读有关实例和静态字段的信息,这将使它更容易理解!这是 Java 教程中的示例文档:https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
本教程将很好地涵盖这一切!
我在制作 Spigot 插件时制作了一个名为 ArrayList<Arena>
的 ArrayList。
public static ArrayList<Arena> all = new ArrayList<Arena>();
现在我有了 class,这是实例化步骤:
public Arena(String name, int min, int max) {
Arena.name = name;
Arena.layout = "default";
Arena.customName = CManager.getPlugin().getArenaConfig().getString("arenas." + name + ".custom-name");
ArenaManager.addToArenaList(this);
ArenaManager.arenaNames.add(Arena.name);
Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.LIGHT_PURPLE + "[" + plugin.getPdfFile().getName()
+ "]" + ChatColor.GREEN + " [#] (Instanciated arena " + Arena.name + ")");
Arena.min = min;
Arena.max = max;
Arena.world = Bukkit.getWorld(Arena.name);
waiting = true;
starting = false;
game = false;
finished = false;
}
我对这段看似简单的代码有疑问。
public static void addToArenaList(Arena a) {
all.add(a);
checkArena(a);
}
public static void checkArena(final Arena a) {
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
public void run() {
if (!(all.contains(a))) {
Bukkit.getServer().getConsoleSender().sendMessage(
ChatColor.LIGHT_PURPLE + "[" + plugin.getPdfFile().getName() + "]" + ChatColor.RED
+ " [E] (Error while adding arena " + a.getArenaName() + "to list)");
} else {
Boolean found = false;
for (Arena f : all) {
if (f.getArenaName().equals(a.getArenaName())) {
if (found == true) {
Bukkit.getServer().getConsoleSender()
.sendMessage(ChatColor.LIGHT_PURPLE + "[" + plugin.getPdfFile().getName() + "]"
+ ChatColor.RED + " [E] (Duplicate found with arena "
+ a.getArenaName());
continue;
}
found = true;
}
}
if (found == false) {
Bukkit.getServer().getConsoleSender()
.sendMessage(ChatColor.LIGHT_PURPLE + "[" + plugin.getPdfFile().getName() + "]"
+ ChatColor.RED + " [E] (Error while adding arena " + a.getArenaName()
+ "to list)");
}
}
}
}, 10L);
}
但出于某种原因,我得到了最后一个竞技场的副本,这也是该过程的第一阶段
public void onEnable() {
Methods.sendColoredMessage(this, ChatColor.LIGHT_PURPLE, ("Registering Commands...."), ChatColor.YELLOW);
registerCommands();
Methods.sendColoredMessage(this, ChatColor.LIGHT_PURPLE, ("Registering Events...."), ChatColor.YELLOW);
registerEvents();
Methods.sendColoredMessage(this, ChatColor.LIGHT_PURPLE, ("Registering Config...."), ChatColor.YELLOW);
createFiles();
Methods.sendColoredMessage(this, ChatColor.LIGHT_PURPLE, ("Attempting to load arenas...."), ChatColor.GOLD);
ArenaManager.all.clear();
ArenaManager.arenaNames.clear();
ArenaManager.createArenas();
Methods.sendColoredMessage(this, ChatColor.AQUA,
(pdfFile.getName() + " has been enabled! (V." + pdfFile.getVersion() + ")"), ChatColor.GREEN);
}
public static void createArenas() {
if (plugin.getArenaConfig().getConfigurationSection("arenas") != null) {
int count = 0;
ArrayList<String> listed = new ArrayList<String>();
for (String arena : plugin.getArenaConfig().getStringList("enabled")) {
count++;
Bukkit.getServer().getConsoleSender()
.sendMessage(ChatColor.LIGHT_PURPLE + "[" + plugin.getPdfFile().getName() + "]"
+ ChatColor.GREEN + " [" + count + "] (Loading arena " + arena + ")");
int min = plugin.getArenaConfig().getInt("arenas." + arena + ".min");
int max = plugin.getArenaConfig().getInt("arenas." + arena + ".max");
new Arena(arena, min, max);
}
Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.LIGHT_PURPLE + "["
+ plugin.getPdfFile().getName() + "]" + ChatColor.GREEN + " [A] Loaded arenas are listed below:");
for (Arena a : all) {
if (listed.contains(a.getArenaName())) {
continue;
}
Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.LIGHT_PURPLE + "["
+ plugin.getPdfFile().getName() + "]" + ChatColor.GREEN + " [A] - " + a.getArenaName());
listed.add(a.getArenaName());
}
} else {
Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.LIGHT_PURPLE + "["
+ plugin.getPdfFile().getName() + "]" + ChatColor.RED + " [E] No arenas have been found!");
}
}
因此,如果我有 4 个竞技场,最后一个叫做 EndArena,在我的数组中,我最终会得到 4 个元素都具有相同的竞技场 class EndArena。我什么都试过了,我通常不喜欢寻求帮助(我更喜欢自己学东西)但这让我很烦恼,所以我不得不提交它。
还有我的竞技场YAML文件
出现这种情况是因为您没有正确使用对象。
据我了解您的代码,您想要创建某种 Arena,为该 Arena 分配一些值,然后将其添加到某个 ArenaManager。这可以。为此,您需要使用实例变量,这样每个创建的 Arena 都会有自己的名称。该特定实例的唯一性。
您在这里使用的是静态字段 - 静态在程序中的所有对象中都是相同的,这不是您在这里需要的(如果您需要竞技场计数器之类的东西,这将是有益的)。
请看一些例子:
想象一下,有一个非常简单和天真的人 class(按照你的方法)。
public class Person {
private static String name;
public Person(String name) {
Person.name = name;
}
}
如果你想做这样的事情: 新人("Adam"); 新人("Viktor");
您将以 2 个 person 实例结束(指向)一个静态变量,该变量最终将具有值 Victor。这肯定不是我们在这里需要的东西。为了使其正常工作,您需要使用实例变量:
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
}
现在,在我们的示例代码之后,您将有 2 个人,每个人都有不同的名字。如何访问它们并不重要,真正重要的是它们应该是实例字段——这意味着每个实例在内存中都有单独的块来保存这个值。如果该字段是静态的,它只是意味着所有不同的对象都有一个可能的变量值 - 每次您更改它都会为所有其他对象更改。
总结一下:
您应该使用实例字段而不是静态字段。
在你的构造函数中你有: Arena.name = 姓名; Arena.layout = "default";
这两行代码总是会覆盖你 Arena 中的静态字段 class。
在你的 Arena class 你有类似的东西(注意静态关键字):
private static String name;
您需要:
private String name;
所以每个实例都有自己的名字。请阅读有关实例和静态字段的信息,这将使它更容易理解!这是 Java 教程中的示例文档:https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html 本教程将很好地涵盖这一切!