HashMap problems

Discussion in 'Plugin Development' started by brord, Dec 11, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    brord

    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 (open)

    Code:java
    1.  
    2.  
    3. public class Match {
    4. FileConfiguration mapconfig;
    5. Config customconfig;
    6. FPSCaste plugin;
    7.  
    8. //maps list
    9. public LinkedList<String> maps;
    10.  
    11. //List of match IDs
    12. public LinkedList<Integer> matchIDs;
    13.  
    14. //match IDs with their current map
    15. public HashMap<Integer, String> Match;
    16.  
    17. //Random value initializer
    18. Random rn = new Random();
    19.  
    20. /**
    21.   * Default constructor.
    22.   */
    23. public Match(FPSCaste instance) {
    24. plugin = instance;
    25. }
    26.  
    27. /**
    28.   * Loader for the Match class
    29.   */
    30. public void load(){
    31. customconfig = new Config(FPSCaste.getInstance());
    32. maps = new LinkedList<String>();
    33. matchIDs = new LinkedList<Integer>();
    34. Match = new HashMap<Integer, String>();
    35. mapconfig = customconfig.getConfig("maps");
    36. loadMaps();
    37. createStartingMatched();
    38. }
    39.  
    40.  
    41. /**
    42.   * Load all maps-related stuff.
    43.   * @return
    44.   */
    45. public void loadMaps()
    46. {
    47. if (mapconfig.getKeys(false).isEmpty()){
    48. plugin.log("No map found", Level.WARNING);
    49. } else {
    50. for (String mapname:mapconfig.getKeys(false)){
    51. String worldname = mapconfig.getString(mapname + ".world");
    52. if (worldname == null || worldname.equals("")){
    53. plugin.log("No world found for map: " + mapname, Level.WARNING);
    54. } else {
    55. maps.add(mapname);
    56. plugin.log("Map found and added: " + mapname, Level.INFO);
    57. plugin.log("Current maps: " + maps, Level.INFO);
    58. }
    59. }
    60. }
    61. }
    62.  
    63. /**
    64.   * Creates a new match on plugin startup
    65.   */
    66. public void createStartingMatched() {
    67. matchIDs.add(1);
    68. System.out.print("matchIDs size = " + matchIDs.size());
    69. int randomMapInt = rn.nextInt(maps.size());
    70. String randomMatch = maps.get(randomMapInt);
    71. Match.put(1, randomMatch);
    72. }
    73.  
    74. /**
    75.   * Function to get maps
    76.   * @return List of maps avaialable
    77.   */
    78. public LinkedList<String> getMaps(){
    79. return maps;
    80. }
    81.  
    82. /**
    83.   * Function to get match IDs
    84.   * @return List of match IDs
    85.   */
    86. public LinkedList<Integer> getIDs(){
    87. return matchIDs;
    88. }
    89.  
    90. public void setMatchMap(Integer ID, String mapname){
    91. Match.put(ID, mapname);
    92. }
    93.  
    94. public int getRandomID() {
    95. if (matchIDs.isEmpty()){
    96. System.out.print("matchIDs is null");
    97. return 1;
    98. } else {
    99. System.out.print("matchIDs is " + matchIDs.size());
    100. return rn.nextInt(matchIDs.size()+1)-1;
    101. }
    102. }
    103.  



    MatchPlayer class (open)

    Code:java
    1.  
    2. public class MatchPlayer {
    3. FPSCaste plugin;
    4.  
    5. //name & matchID
    6. public HashMap<String, Integer> IngamePlayers;
    7.  
    8. //Name and stats
    9. /**
    10.   * String[0] = Player name
    11.   * String[1] = Team
    12.   * Integer[0] = kills
    13.   * Integer[1] = deaths
    14.   * Integer[2] = assists
    15.   */
    16. public HashMap<String, Integer[]> PlayerStats;
    17.  
    18. //Name and team
    19. public HashMap<String, String> Playerteam;
    20.  
    21. public MatchPlayer(FPSCaste plugin) {
    22. this.plugin = plugin;
    23. PlayerStats = new HashMap<String, Integer[]>();
    24. Playerteam = new HashMap<String, String>();
    25. IngamePlayers = new HashMap<String, Integer>();
    26. }
    27.  
    28. public void putPlayer(String name, Integer matchID){
    29. IngamePlayers.put(name, matchID);
    30. }
    31.  
    32. public HashMap<String, Integer> getIngamePlayers(){
    33. return IngamePlayers;
    34. }
    35.  
    36. public int getPlayer(String name){
    37. System.out.print(IngamePlayers.toString());
    38. System.out.print(PlayerStats.toString());
    39. return IngamePlayers.get(name);
    40. }
    41.  
    42. @SuppressWarnings("unused")
    43. public String getPlayerCurrentMap(String name){
    44. MatchPlayer player = new MatchPlayer(FPSCaste.getInstance());
    45. Match match = new Match(plugin);
    46.  
    47. int matchID = player.getPlayer(name);
    48. String mapname = match.Match.get(matchID);
    49. return "map1";
    50. }
    51.  
    52. void updateStats(String name, Integer[] stats){
    53. PlayerStats.put(name, stats);
    54. }
    55.  



    JoinGame command code (open)

    Code:java
    1.  
    2. public void joinGame(CommandSender sender){
    3. Match match = new Match(plugin);
    4.  
    5. int ID = match.getRandomID();
    6. MatchPlayer player = new MatchPlayer(plugin);
    7. player.IngamePlayers.put(sender.getName(), ID);
    8. Bukkit.getLogger().log(Level.SEVERE, player.IngamePlayers.toString());
    9. Bukkit.getLogger().log(Level.SEVERE, match.matchIDs.size() + " = the size of matchIDs");
    10. Bukkit.getLogger().log(Level.SEVERE, match.Match.toString() + " = the values of match");
    11. teleportToGame(sender.getName());
    12. }
    13.  
    14.  
    15.  





    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!
     
  2. Offline

    fireblast709

    brord
    1. you create a new MatchPlayer instance at the joinGame() methods, so the values never get added
    2. that instance gets cleared after the method, as it falls outside of the scope
     
  3. Offline

    Barinade

    Extend your main class then just do "IngamePlayers.put.." etc.
    and remove
    MatchPlayer player = new MatchPlayer(plugin);
     
  4. Offline

    brord

    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?
     
  5. Offline

    Barinade

    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
     
  6. Offline

    brord

    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
     
  7. Offline

    fireblast709

    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
     
  8. Offline

    brord

    fireblast709
    So typing:
    "FPSCaste main = new FPSCaste();"
    "main.[hashmapname].get/put(xxx,xx)"

    in almost every class, is better then setting hash to static?
     
  9. Offline

    fireblast709

    well something close to that
    Code:java
    1. public FPSCaste main
    2. public <class name>(FPSCaste m)
    3. {
    4. this.main = m;
    5. }

    And yes, better than static
     
  10. Offline

    brord

    fireblast709
    Last question :D
    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?
     
  11. Offline

    fireblast709

    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')
     
  12. Offline

    brord

    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.
     
    Last edited by a moderator: May 30, 2016
  13. Offline

    fireblast709

    just a sidenote: Java passes objects as references, so you should not use up more resources :3
     
  14. Offline

    brord

    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)
     
  15. Offline

    Barinade

  16. Offline

    fireblast709

    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()
     
  17. Offline

    brord

    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 :)
     
  18. Offline

    fireblast709

    brord *whispers : "(nullify them with '= null' ;3)"*
     
  19. Offline

    brord

Thread Status:
Not open for further replies.

Share This Page