好的,自从我在Bukkit API上更改了我的菜单设计后,我就遇到了这个奇怪的错误。
在我强调问题之前,这是程序应该做的事情。
直到第2步它正常,但是步骤3中的事件似乎被注册等于HashMap内的键数量。例如,如果3个玩家在线,则第4个玩家将被注册 x4次,这是一个严重的内存泄漏。
现在这里是我的代码,它是整个班级。
package src.ares.core.menu;
import java.util.ArrayList;
import java.util.HashMap;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import src.ares.core.Main;
import src.ares.core.common.Module;
public class MenuListener extends Module
{
private static MenuListener instance = new MenuListener();
public static MenuListener getInstance()
{
return instance;
}
private HashMap<Player, ArrayList<Menu>> activeMenus;
public MenuListener()
{
super("Menu Listener");
this.activeMenus = new HashMap<>();
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event)
{
Player player = event.getPlayer();
ArrayList<Menu> defaultMenus = new ArrayList<>();
defaultMenus.add(MenuFactory.getFactory().createMenu(MenuType.KIT_MENU));
defaultMenus.add(MenuFactory.getFactory().createMenu(MenuType.WORLD_MENU));
defaultMenus.add(MenuFactory.getFactory().createMenu(MenuType.STATS_MENU));
if (!activeMenus.containsKey(player))
activeMenus.put(player, defaultMenus);
else return;
Main.debug("Before For-Loop.");
for (Player registered : activeMenus.keySet())
{
if (registered.equals(player))
{
Main.debug("Player Validation Passed -> " + registered.getName());
ArrayList<Menu> playerMenus = activeMenus.get(registered);
for (Menu specificMenu : playerMenus)
{
specificMenu.setSpecificTo(registered);
specificMenu.addItems();
specificMenu.defineItems();
specificMenu.registerEvents();
Main.debug("Messing with -> " + specificMenu.getName());
}
Main.debug("End of Menus.");
}
}
}
public HashMap<Player, ArrayList<Menu>> getMenus()
{
return activeMenus;
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event)
{
for (Player registered : activeMenus.keySet())
{
if (registered.equals(event.getPlayer()))
{
for (Menu playerMenu : activeMenus.get(registered))
{
playerMenu.destroy();
}
activeMenus.remove(registered);
Main.debug("Unregistering Menu Listeners.");
}
}
}
}
所以我的问题是。 什么可能解决事件的问题? 除此之外,其他一切都很完美。
抬头,我从昨天开始调试,没有进展。
答案 0 :(得分:1)
我很好奇你的for循环,所以我用Strings替换了大部分对象,并调用onPlayerJoin()四次来测试它。
Player Validation Passed -> aaaaa
Messing with -> MenuType.KIT_MENU
Messing with -> MenuType.WORLD_MENU
Messing with -> MenuType.STATS_MENU
End of Menus.
Player Validation Passed -> bbbbb
Messing with -> MenuType.KIT_MENU
Messing with -> MenuType.WORLD_MENU
Messing with -> MenuType.STATS_MENU
End of Menus.
Player Validation Passed -> ccccc
Messing with -> MenuType.KIT_MENU
Messing with -> MenuType.WORLD_MENU
Messing with -> MenuType.STATS_MENU
End of Menus.
Player Validation Passed -> ddddd
Messing with -> MenuType.KIT_MENU
Messing with -> MenuType.WORLD_MENU
Messing with -> MenuType.STATS_MENU
End of Menus.
所有东西只被调用一次,我看到没有像OP中描述的玩家数量的循环。在我看来,你的循环方式没有任何问题,而是Bukkit的实现。
对我来说有一件事是在onPlayerJoin()中你是如何拥有Player&#34; player&#34;然后循环访问keySet以找到同一个播放器并调用它#34;注册&#34;。
Main.debug("Before For-Loop.");
for (Player registered : activeMenus.keySet())
{
if (registered.equals(player))
{
Main.debug("Player Validation Passed -> " + registered.getName());
ArrayList<Menu> playerMenus = activeMenus.get(registered);
我试过调查Player.equals(播放器)并且似乎对某些人来说是错误的。我会:
,而不是存储和比较玩家的实例Player.getUniqueId();
if (registered.getUniqueId() == player.getUniqueId())
。但是,在您的情况下,通过替换&#34;已注册的&#34;的所有实例,无法完全避免比较。到&#34;玩家&#34;?
Main.debug("Before For-Loop.");
// for (Player registered : activeMenus.keySet())
// {
// if (registered.equals(player))
// {
Main.debug("Player Validation Passed -> " + player.getName());
ArrayList<Menu> playerMenus = activeMenus.get(player);
来源: