HashMap for several values?

Discussion in 'Plugin Development' started by kyle1320, Aug 11, 2012.

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

    kyle1320

    Can I create a HashMap with more than 1 value per key? Is there something similar to a HashMap with this feature?
     
  2. Offline

    Phil2812

    Just create a HashMap containing a list or even another HashMap as value.
    Like HashMap<String,List<String>> or HashMap<String,SortedMap<String,Object>> or HashMap<String,SortedMap<String,TreeMap<String,Object>>> (you get the idea...)
     
  3. Offline

    kyle1320

    Okay thanks, I'll try it.
     
  4. Offline

    skore87

    There is always the option to creating your own custom class that can return anything you choose.
     
  5. Offline

    sayaad

    And there is also the option of useing an ArrayList<String> that contains a formatted string that you split and parse into the variables you want.
     
  6. Offline

    skore87

    string manipulation is pretty slow XD
     
  7. Offline

    kyle1320

    I need something that will store 2 players and 1 boolean value. I should be able to get the boolean using either player to retrieve it, but should also be able to differentiate between the players. Is there a nice way to set something like this up? I'm not having much luck at this. :/

    Edit: It also shouldn't support duplicates ಠ_ಠ
     
  8. Offline

    sayaad

    Simple. Using my method you can store it like this :

    <---- Now click on my name and view my status (its under my name in the javascript window that pops up)

    example format :

    playerOne'sName:booleanValueForPlayerOne;playerTwo'sName:booleanValueForPlayerTwo

    split by ";" first and the string array will be :

    array[0] == "playerOne'sName:booleanValueForPlayerOne"
    array[1] == "playerTwo'sName:booleanValueForPlayerTwo"

    Then its like 2 hashmap values from there.

    and useing arraylist is easy to tell if the string exists : if(arrayList.contains("Stringvalue")){

    I HATE HASHMAPS! PERIOD.
     
  9. Offline

    kyle1320

    So I'm creating an array and skipping hashmaps altogether?
     
  10. Offline

    Courier

    Do you need to be able to get one player from the other player? If you only need to get the boolean, but you want it to be linked to both player, it would be pretty simple. Just add both names as keys, each associated with the same value.
    Code:java
    1. //Java7 generic constructor sugar
    2. HashMap<String, MutableBoolean> myMap = new HashMap();
    3. private void addNewPair(Player p1, Player p2, boolean bool)
    4. {
    5. MutableBoolean mbool = new MutableBoolean(bool);
    6. myMap.put(p1.getName(), mbool);
    7. myMap.put(p2.getName(), mbool);
    8. }
    9.  
    10.  
    11. private void set(Player p, boolean bool)
    12. {
    13. MutableBoolean mbool = myMap.get(p.getName());
    14. if(mbool == null)
    15. throw new IllegalArgumentException("Player is not in a registered pair!");
    16. mbool.value = bool;
    17. //now calling myMap.get(p).value will return the new value,
    18. //and so will calling myMap.get(<p's partner>).value
    19. }
    20. ...
    21.  
    22. class MutableBoolean
    23. {
    24. public boolean value;
    25. public MutableBoolean(boolean value) {this.value = value;}
    26. }
     
  11. Offline

    kyle1320

    Sadly, yes.
     
  12. Offline

    Courier

    So he has to parse a bunch (on average, half) of entries in the ArrayList<String> when he wants to search for a player? That is not very efficient.
    Umm no... that would only work if he is searching for the exact String, which would mean he would have to already know the boolean values of each player, as well as their order.
    You really shouldn't. They are way more efficient than Lists. HashMaps are scalable, ArrayLists are not. Writing plugins that do not perform well on large servers is sloppy and gross.
     
  13. Offline

    Phinary

    Its been stated before, but I highly suggest you just create a new class, then make a hashmap that creates instances of that class. Then you can store pretty much as much data as you want, and is very simple if you need to modify / add anything
     
  14. Offline

    Courier

    Hmm. Okay. It won't be quite as simple then. This is a rough example.
    Code:java
    1. HashMap<String, Partner> myMap = new HashMap();
    2. private void add(Player p1, Player p2, boolean bool)
    3. {
    4. MutableBoolean mbool = new MutableBoolean(mbool);
    5. Partner part1 = new Partner(p1, p2, mbool);
    6. Partner part2 = new Partner(p2, p1, mbool);
    7. mySet.add(p1.getName(), part1);
    8. mySet.add(p2.getName(), part2);
    9. }
    10.  
    11. private String getPartner(String playerName)
    12. {
    13. Partner part = myMap.get(playerName);
    14. if(part == null)
    15. throw new IllegalArgumentException("This player does not have a partner!");
    16. return part.partnerName;
    17. }
    18.  
    19. private void setBoolean(String playerName, boolean toValue)
    20. {
    21. //this method does exactly the same thing no matter which of the partner's names is passed in
    22. //it sets the value for both partners, since they share the same MutableBoolean object
    23. Partner part = myMap.get(playerName);
    24. if(part == null)
    25. throw new IllegalArgumentException("This player does not have a partner!");
    26. part.bool.value = toValue;
    27. }
    28. ...
    29. class Partner
    30. {
    31. public final String partnerName;
    32. public final MutableBoolean bool;
    33.  
    34. public Partner(Player part, MutableBoolean mbool)
    35. {
    36. this.partnerName = part.getName();
    37. this.value = mbool;
    38. }
    39. }
    40. ...
    41. class MutableBool
    42. ... //same as above post
     
  15. Offline

    kyle1320

    I'll do my best to combine these ideas, wish me luck and thanks for the help.
     
  16. Offline

    HamOmlet

    Have you considered using Google's Guava library? It looks as though you want a Multimap, which can be used to assign multiple values to a single key.
     
  17. Offline

    kyle1320

    Is it possible to use this to assign multiple values of different types to the same key? The 'presidents' example didn't make this clear.

    Also, I need a way to set up a 15 second timer, that would start when called and do something after 15 seconds. I tried messing around with getServer().getScheduler() stuff, but couldn't seem to figure it out. There also doesn't seem to be much online about this, but maybe I'm just not looking in the right places.
    How can I delay a task that takes arguments?
     
  18. Offline

    skore87

    Often people will create an anonymous class as the Runnable when making a delayed task like this:
    Code:
    plugin.getServer().getScheduler().scheduleSyncDelayedTask(new Runnable(){
    @Override
    public void run(){
    // code
    }
    },200L);
    But in your case, you want to pass information into this task. So to do so, you will need to create a new class. I personally prefer to create a new class file rather than defining it in the same.
    Code:
    package yourpackage;
    public class yourschedulername implements Runnable{
      private String argument;
     
      public yourschedulername(String argument1){
          this.argument = argument1;
      }
     
      @Override
      public void run(){
          // task's code
      }
    }
    
    And now to execute it:
    Code:
    plugin.getServer().getScheduler().scheduleSyncDelayedTask(new yourschedulername("A string for example"),200L);
     
    // or
    yourschedulername sched = new yourschedulername("A string for example");
    plugin.getServer().getScheduler().scheduleSyncDelayedTask(sched,200L);
     
  19. Offline

    kyle1320

    It works, thanks!
     
Thread Status:
Not open for further replies.

Share This Page