Solved HashMap Problem - Same values in 2 different keys

Discussion in 'Spigot Plugin Development' started by Xearox, May 31, 2016.

  1. Hey there,

    I am actually working on my xDaily plugin and I've got some trouble with HashMaps.

    I never worked before with HashMaps(maybe that's the problem or maybe not dunno).

    I defined a hashmap in my MainClass XDaily.java as "public static" to save the last inventory which the player have opened after switch to an other inventory. That is the reason why I defined it in the MainClass.

    This is my HashMap:

    Code (Java):
    public static Map<UUID, ArrayList<Inventory>> lastInventoryMap = new HashMap<>();

    Now if the player opened the next inventory in the GUI it will save the UUID as key and the inventory as value in the hashmap.

    Now if an other player do the same, the last inventory save in both keys! But I don't know why, because the other player has an different UUID!

    Here a picture of that(You see some debug stuff on it).

    2016-05-31 01_51_49-start.bat.png

    My code you can find on GitHub:
    https://github.com/Xearoxde/Maven/b...ava/de/xearox/xdaily/adminGUI/GuiActions.java

    There are a lot of System.out(); to find the problem by myself but I haven't found it :(

    Maybe you can help.

    I am very thankful for your help.

    Thanks =)
     
  2. I don't know what the hell you're saying, and your code is too messy to read, but i'll attempt to.. help..

    First off, why are you passing an array to your "runActions" method? You don't do anything with that array other then assign the first element to a variable.. Why not just pass a single reference rather then an array...?

    I'll try to explain what i believe is your issue rather then attempting to translate wtf you're saying. A hashmap requires a unique key to map the value variable to a hashtable. You can have duplicated values assigned to multiple keys, it does not matter. What you cannot have is duplicate keys.
     
  3. Yes, my code is actually messy because I have a lot off stuff to debug the code! But I've changed it now.

    But I try to explain what I want to say.

    I have a hashmap. The hashmap has a key(UUID) and a value(Inventory ArrayList). The hashmap is defined in the MainClass.

    If a player run the command "/daily admin" the plugin get an inventory named "xDaily Admin - Index".

    If the hashmap doesn't contain a key named from the UUID of the player it will create a new ones. If it contains a key like the UUID from the player, it loads the value from the key into the lastInventory ArrayList in the ActionGUI class!

    This can you find here: https://github.com/Xearoxde/Maven/b...de/xearox/xdaily/adminGUI/GuiActions.java#L45

    In the "xDaily Admin - Index" inventory you can click on an item named "Create New..." ... If the player click on it, it will create a new inventory named "xDaily Admin - Create New...". Now I use the hashmap to save the previous inventory of the player.

    This you can find here: https://github.com/Xearoxde/Maven/b...de/xearox/xdaily/adminGUI/GuiActions.java#L64

    and in the next line the value from the key UUID from the player will be replaced with the new value Inventory ArrayList which was create in this class.

    If I go now to the last page, it contains 2 pages((inventories) (2 entries in the ArrayList)). If I go now on the server with an other Minecraft Account and I do the same steps above, the key values of the first player increase too with the same inventories from the second Account.

    This you can see on the picture above!

    My problem is now...Why? Why it increased the first key named from the first players UUID instead the key named from the second players UUID.
    It also saved twice. In the first and second key are the same inventories!

    I don't really know why!
     
  4. You're putting the same ArrayList in the map... but thats only what i gathered from looking at this for a minute
     
  5. What is the point of storing these inventories like you are doing? (XY Problem)

    From what I can tell from a glance, you're sharing the same ArrayList instance between Players, which would mean every key's values point to the same instance, making them effectively identical.
     
  6. I wrote that before I scrolled down, and regardless I added a lot more explanation and information than you did, whilst also trying to find out what the real problem was. No need to try and claim things.
     
  7. I have a single suggestion for you:

    Initialize your Hashmap like this
    Code (Text):
    Hashmap<UUID,Inventory> invs = new HashMap<>();

    invs.put(someUniqueId,someInv);

    invs.get(someUniqueId); //YOU GIVE ME KEY, I GIVE YOU STUFF BACK!

     
    I actually just got done changing my Bottomless Chests
    Inventory Management over to a HashMap from an ArrayList
    and I could not believe how smooth the conversion went over.


    When I make major changes to my plugins, things... ok I'll say it...
    Things never go as smoothly as the change to HashMaps did.
     
  8. It's hard to explain for me. Maybe is my English not the best :D

    What I am trying to do is following: I want to save the last inventory he was in, like the "back button" in your browser. That is the reason why I create a hashmap on the start of the plugin. I haven't the knowledge to do it in an other way. Maybe you have some hints for me.

    I am very confused about that, that my way doesn't work. I thought if I initialize the hashmap on the start of the plugin it can be accessed every time.
    I hope you can understand me. My way is wrong. I know that now but I don't have the knowledge for an other way.
     
  9. https://www.spigotmc.org/wiki/how-to-learn-java-programming/ (inb4 i just put this link in my signature..)

    You are using the same ArrayList variable for every player, You need to brush up on basic programming.

    Why save the ArrayList there, if you are just going to put it in the HashMap? There is no reason to save it between uses, just pull a list out of the HadhMap, modify it, and put it back in the same entry.
     
  10. I don't need your link "how to learn java" ;-)

    I figured it out now.

    In my MainClass it put this in:
    Code (Java):
    private HashMap<UUID, ArrayList<Inventory>> lastInventoryMap;
        public HashMap<UUID, ArrayList<Inventory>> getLastInventoryMap(){
            return lastInventoryMap;
        }
    In the GuiAction Class I put this in:
    Code (Java):
    public class GuiActions {

        private XDaily plugin;
       
        private HashMap<UUID, ArrayList<Inventory>> lastInventoryMap;
       
        private String inventoryName = "xDaily Admin - ";
       
        public GuiActions(XDaily plugin) {
            this.plugin = plugin;
            this.lastInventoryMap = plugin.getLastInventoryMap();
        }
     
    Code (Java):
    public void runActions(Player player,InventoryClickEvent...events){
            InventoryClickEvent event;
            ArrayList<Inventory> inventory = new ArrayList<>();
    This is working now!
     
  11. Yes, but will it work if multiple people use it at the same time? Some very strange things will happen.
     
  12. Yes. It works!

    2016-06-03 21_24_27-start.bat.png


    The number behind the UUID is the size of the ArrayList. Every UUID has an other ArrayList but they use the same HashMap.

    My menu is not really big. Maybe I have later some problem but actually it's working!

    Note: Maybe it's not working if two or more player are clicking on the same time on an item. But this I can't test xD I can't click twice on 2 different games xD