Hey guys! Im in trouble bigtime this time. I have these HashMaps, whih i populate with a value on startup, but once i try to get these values again, they are gone. I tried everything, troubleshooted with system.out.print(), and even made a command to show all the hashmaps. please take your time to read my code(I do not yet fully understaind HashMaps yet, learned about them yesterday) Match class (Move your mouse to reveal the content) Match class (open) Match class (close) Code:java public class Match { FileConfiguration mapconfig; Config customconfig; FPSCaste plugin; //maps list public LinkedList<String> maps; //List of match IDs public LinkedList<Integer> matchIDs; //match IDs with their current map public HashMap<Integer, String> Match; //Random value initializer Random rn = new Random(); /** * Default constructor. */ public Match(FPSCaste instance) { plugin = instance; } /** * Loader for the Match class */ public void load(){ customconfig = new Config(FPSCaste.getInstance()); maps = new LinkedList<String>(); matchIDs = new LinkedList<Integer>(); Match = new HashMap<Integer, String>(); mapconfig = customconfig.getConfig("maps"); loadMaps(); createStartingMatched(); } /** * Load all maps-related stuff. * @return */ public void loadMaps() { if (mapconfig.getKeys(false).isEmpty()){ plugin.log("No map found", Level.WARNING); } else { for (String mapname:mapconfig.getKeys(false)){ String worldname = mapconfig.getString(mapname + ".world"); if (worldname == null || worldname.equals("")){ plugin.log("No world found for map: " + mapname, Level.WARNING); } else { maps.add(mapname); plugin.log("Map found and added: " + mapname, Level.INFO); plugin.log("Current maps: " + maps, Level.INFO); } } } } /** * Creates a new match on plugin startup */ public void createStartingMatched() { matchIDs.add(1); System.out.print("matchIDs size = " + matchIDs.size()); int randomMapInt = rn.nextInt(maps.size()); String randomMatch = maps.get(randomMapInt); Match.put(1, randomMatch); } /** * Function to get maps * @return List of maps avaialable */ public LinkedList<String> getMaps(){ return maps; } /** * Function to get match IDs * @return List of match IDs */ public LinkedList<Integer> getIDs(){ return matchIDs; } public void setMatchMap(Integer ID, String mapname){ Match.put(ID, mapname); } public int getRandomID() { if (matchIDs.isEmpty()){ System.out.print("matchIDs is null"); return 1; } else { System.out.print("matchIDs is " + matchIDs.size()); return rn.nextInt(matchIDs.size()+1)-1; } } MatchPlayer class (Move your mouse to reveal the content) MatchPlayer class (open) MatchPlayer class (close) Code:java public class MatchPlayer { FPSCaste plugin; //name & matchID public HashMap<String, Integer> IngamePlayers; //Name and stats /** * String[0] = Player name * String[1] = Team * Integer[0] = kills * Integer[1] = deaths * Integer[2] = assists */ public HashMap<String, Integer[]> PlayerStats; //Name and team public HashMap<String, String> Playerteam; public MatchPlayer(FPSCaste plugin) { this.plugin = plugin; PlayerStats = new HashMap<String, Integer[]>(); Playerteam = new HashMap<String, String>(); IngamePlayers = new HashMap<String, Integer>(); } public void putPlayer(String name, Integer matchID){ IngamePlayers.put(name, matchID); } public HashMap<String, Integer> getIngamePlayers(){ return IngamePlayers; } public int getPlayer(String name){ System.out.print(IngamePlayers.toString()); System.out.print(PlayerStats.toString()); return IngamePlayers.get(name); } @SuppressWarnings("unused") public String getPlayerCurrentMap(String name){ MatchPlayer player = new MatchPlayer(FPSCaste.getInstance()); Match match = new Match(plugin); int matchID = player.getPlayer(name); String mapname = match.Match.get(matchID); return "map1"; } void updateStats(String name, Integer[] stats){ PlayerStats.put(name, stats); } JoinGame command code (Move your mouse to reveal the content) JoinGame command code (open) JoinGame command code (close) Code:java public void joinGame(CommandSender sender){ Match match = new Match(plugin); int ID = match.getRandomID(); MatchPlayer player = new MatchPlayer(plugin); player.IngamePlayers.put(sender.getName(), ID); Bukkit.getLogger().log(Level.SEVERE, player.IngamePlayers.toString()); Bukkit.getLogger().log(Level.SEVERE, match.matchIDs.size() + " = the size of matchIDs"); Bukkit.getLogger().log(Level.SEVERE, match.Match.toString() + " = the values of match"); teleportToGame(sender.getName());} I load the game by calling load() from the Match class, and when i print out the result, it works fine. Once i try to typ /join, values dissapear. Could anyone be kindly enough to explain me what is going on? :3 fireblast709 Thanks!
brord you create a new MatchPlayer instance at the joinGame() methods, so the values never get added that instance gets cleared after the method, as it falls outside of the scope
Extend your main class then just do "IngamePlayers.put.." etc. and remove MatchPlayer player = new MatchPlayer(plugin);
How would i go about that when my class requires both Match.class and MatchPlayer.class? Anbd every command extends AbstractFPSCasteCommand allready, so that will mean i cant use hashmaps for a command direcly. Or should i just make one class which holds every hashmap?
Keep all your hashmaps in your main class and extend the main class when you need them, or do MainClass.HashMap.put(etc) Edit: change the hashmaps to static as well
Ye i got the static part Im not a beginner. Thanks for the options, i will defenitely try it out once i wake up again --edit Wait, with main class you mean the one that extends JavaPlugin right? Not like a new class just for hashmaps, which would be cleaner in my opinion
Don't use static, causes memory leaks... Pass your main class (yes, the one extending JavaPlugin) to the class where you need it, via the constructor
fireblast709 So typing: "FPSCaste main = new FPSCaste();" "main.[hashmapname].get/put(xxx,xx)" in almost every class, is better then setting hash to static?
well something close to that Code:java public FPSCaste mainpublic <class name>(FPSCaste m){ this.main = m;} And yes, better than static
fireblast709 Last question Is it better to define the full hashmap immedately -> public LinkedList<String> maps = new LinkedList<String>(); or define the second part on, load() for example -> maps = new LinkedList<String>(); if it even matters --- edit FPSCaste main = new FPSCaste(); works, how is that what you wrote better?
My version uses one variable, and the rest references that. Your version makes a different class each time (so no reliability that the variables can be set and other classes will see them that way), and is error-prone :3. Also, it should not matter that much at this point (the 'HashMap defining')
Okay! thanks for the help once again <3 @fireblast709 Barinade Allright, i have tried everything, but none of the options were usable for my plugin structure. A lot of my classes need vars from the hashmap, but those classes sometimes extend others. So i cant make them extend a class with vars. But making all the hashmaps in the main class, and calling that with the constructor will not work either, because not every class has the "FPSCaste plugin;" initiazised, and doing so will be a waste of resources, and will make the code more complicated as it should be. How do you guys write your plugins so that hashmaps can be used in every class, but without over-complicated code? I never had to use OOP java, so i dont know how to make the right structures. And looking at, mobarena, for example, does not help me because its waaay to advanced for me. Could anyone help me out and or give me a psuedo code classes to get starting with, that would help me out greatly! Thanks in advance, kwek20 or brord EDIT by Moderator: merged posts, please use the edit button instead of double posting.
Resources is not my point, i have enough of that. ANd besides, this will be the only plugin running, so its okay. Could you, by any chance give explaining "how a good hashmap structure, and those classes with them" me a shot? (I can send the entire source code, but its pretty big, and i dont use GIT)
You might say that static is a solution, but it only causes memory leaks. IF you are going to use it, try keeping all statics in one class and null them onDisable()
Ye, i made a class with all the hashmaps now. Those are all static so i can easily acces/write them. those will be the ONLY static in the entire plugin, so i guess it will be Okay. And, good one, ill write null's on disable