Solved Saving per player info to VM

Discussion in 'Spigot Plugin Development' started by Sonacabon, Jun 20, 2016.

Thread Status:
Not open for further replies.
  1. Hi, well today I got some sort of a nooby issue, but I am not really good with hashmaps so what I am trying to do exactly is save how many times players break blocks only during the time span of the server without saving it to the actual storage, this is what I have right now
    Code (Text):
    HashMap<Player, Integer>  = new HashMap<Player, Integer>();
    @EventHandler
    public void onBlockBreak(BlockBreakEvent e) {
        Player p = (Player) e.getPlayer();
        PBlockBreak.put(p, 1)
        //here I want to check if the player has already broken 5000 blocks
    }
    I am not completely sure my code works completely, but again I am pretty bad at hashmaps.

    EDIT: Here is a new sample for anyone else looking for answers and didn't understand others explanations.
    Code (Text):

    HashMap<Player, Integer>  = new HashMap<Player, Integer>();
    @EventHandler
    public void onBlockBreak(BlockBreakEvent e) {
        Player p = (Player) e.getPlayer();
         if(!PBlockBreak.containsKey(p)){ // Checks if the Map contains the player key (in this case it doesn't)
             PBlockBreak.put(p, 1); // here is adds this players key with the value of 1 (since he already broken a block)
         }else{
             PBlockBreak.put(p, PBlockBreak.get(p) + 1); // here it gets the normal value stored for the player and adds 1 to it (since the player is already stored in the hashmap)
         if(PBlockBreak.get(p) == 5000) { // here it checks if the player's value is 5000
            Bukkit.broadcastMessage(ChatColor.GREEN + p.getName() + " has acquired 5000 block breaks during this session!");
            PBlockBreak.remove(p); //here it removes the players stats, so next block he breaks will restart at 1 since it is no longer in the Map.
         }
    }
    EDIT 2: I just realized I made a mistake in the sample code, using "p.getName()" might give errors and is not needed, now it is removed.
     
    #1 Sonacabon, Jun 20, 2016
    Last edited: Jun 20, 2016
  2. I suppose PBlockBreak is your map?

    Summing it up, a Map is a key-value storage.

    You can do what you want with some simple operations:
    • Get the value from your map. You can get the value linked to a key with Map#get, keep in mind that this can return null values, change your code in order to handle that situation.
    • Do your operations with the value. Increment and check if it's bigger than 5000 in this case, right?
    • Set the value back to the map. Put the value back on the map with Map#put. It doesn't allow duplicate keys, so, don't worry about getting rid of the old one.
     
  3. When you put a value into a HashMap (or any type of Map), the value you give it overwrites whatever is currently there. By using this line:
    Code (Java):
    PBlockBreak.put(p, 1)
    No matter how many blocks they break, the HashMap will only ever store a value of one.




    You have to check if the player is already in the HashMap. If they aren't then you can use:
    Code (Java):
    PBlockBreak.put(p, 1)
    If they are already in the HashMap, then you have to use:
    Code (Java):
    PBlockBreak.put(p, PBlockBreak.get(p) + 1)
     
  4. In java 8 Maps have some new methods that take advantage of lambdas. One of those methods is 'compute' which will calculate the new mapping for a key.

    Code (Text):
    myMap.compute (key, (k, v) -> v == null ? 1 : v + 1)
    What this code does is check if 'v' is null meaning that the mapping doesnt exist yet and if so, just store 1 as this is the first block being broken. Otherwise the mapping will be 1 more than the current value.
     
    • Useful Useful x 1
  5. Correct
     
  6. I did not know about this, but when it comes down to it, the only bonus is having a few less lines of code correct? It still has to perform all the checks we'd have to type ourselves instead right? Or is it more efficient somehow?
     
  7. It does have a bit of a performance boost because you only preform one lookup instead of 2 (1 for the get and another for the put).
     
  8. Alright thanks everyone for the help, it is working now.
     
Thread Status:
Not open for further replies.