Check if two values are in the same key (Hashmap)

Discussion in 'Plugin Development' started by EndureBlackout, Aug 13, 2016.

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

    EndureBlackout

    Hello, so I am making a party plugin and trying to check if two players are in the same part of a hashmap. I have tried multiple things but no luck here is all the code I have right now:
    Code:
    package me.endureblackout.partytime;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.entity.EntityDamageByEntityEvent;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class PartyTimeMain extends JavaPlugin implements Listener {
       
        public Map<String, List<String>> party = new HashMap<>();
        public ArrayList<String> members = new ArrayList<String>();
        public HashMap<String, String> waiting = new HashMap<String, String>();
       
        public void onEnable() {
            getLogger().info("PartyTime enabled!");
        }
       
        public void onDisable() {
            getLogger().info("PartyTime disabled!");
        }
       
        @EventHandler
        public void onPlayerDamagePlayer(EntityDamageByEntityEvent e) {
            if(e.getDamager() instanceof Player && e.getEntity() instanceof Player) {
                Player hit = (Player) e.getEntity();
                Player hitter = (Player) e.getDamager();
               
                Set<String> key = party.keySet();
                if(party.get(key.iterator()).contains(hit.getName()) && party.get(key.iterator()).contains(hitter.getName())) {
                    e.setCancelled(true);
                    hitter.sendMessage("You can't hit players in your party!");
                }
            }
        }
    
        @EventHandler
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
           
            if(cmd.getName().equalsIgnoreCase("party")) {
                if(args.length != 1) {
                    sender.sendMessage("Not enough args!");
                }
                if(args.length == 1 && args[0].equalsIgnoreCase("create")) {
                    Player p = (Player) sender;
                    members.add(p.getName());
                    party.put(p.getName(), members);
                    sender.sendMessage("Party created!");
                } else if(args.length == 2 && args[0].equalsIgnoreCase("add")) {
                    if(!(party.containsKey(sender.getName()))) {
                        sender.sendMessage(ChatColor.RED + "You are not the owner of the party or do not belong to a party");
                    } else {
                        sender.sendMessage(ChatColor.GREEN + args[1] + " has been invited to the party!");
                        for(Player p : Bukkit.getOnlinePlayers()) {
                            if(p.getName() == args[1]) {
                                p.sendMessage("You were invited to a party by " + sender.getName());
                            }
                        }
                        waiting.put(args[1], sender.getName());
                    }
                } else if(args.length == 1 && args[0].equalsIgnoreCase("accept")) {
                    if(waiting.containsKey(sender.getName())) {
                        String partyName = waiting.get(sender.getName());
                        List<String> list = party.get(partyName);
                        list.add(sender.getName());
                        party.put(partyName, list);
                        waiting.remove(sender.getName());
                        sender.sendMessage(ChatColor.GREEN + "Party invite accepted!");
                       
                        for(Player p : Bukkit.getOnlinePlayers()) {
                            if(party.get(partyName).contains(p.getName())) {
                                p.sendMessage(ChatColor.GREEN + sender.getName() + " has joined the party!");
                            }
                        }
                    }
                } else if(args.length == 1 && args[0].equals("check")) {
                    if(!(party.containsKey(sender.getName()))) {
                        sender.sendMessage("You are not a party leader!");
                    } else if(party.containsKey(sender.getName())) {
                        List<String> list = party.get(sender.getName());
                        sender.sendMessage(list + "");
                    }
                } else if(args.length == 2 && args[0].equalsIgnoreCase("kick")) {
                    if(party.containsKey(sender.getName()) && party.get(sender.getName()).contains(args[1])) {
                        party.get(sender.getName()).remove(args[1]);
                    }
                }
            }
           
            return false;
            }
    
    }
    
    Here is where my issue is:
    Code:
        @EventHandler
        public void onPlayerDamagePlayer(EntityDamageByEntityEvent e) {
            if(e.getDamager() instanceof Player && e.getEntity() instanceof Player) {
                Player hit = (Player) e.getEntity();
                Player hitter = (Player) e.getDamager();
               
                Set<String> key = party.keySet();
                if(party.get(key.iterator()).contains(hit.getName()) && party.get(key.iterator()).contains(hitter.getName())) {
                    e.setCancelled(true);
                    hitter.sendMessage("You can't hit players in your party!");
                }
            }
        }
     
  2. Offline

    Lolmewn

    Why not store a Player -> Party relation? You can just check if player.getParty().equals(otherPlayer.getParty()) for example.
     
  3. Offline

    MCMastery

    But ofc, use UUIDs instead of Players :)
     
  4. Offline

    mythbusterma

    @Lolmewn @MCMastery

    You could, but I think a Set of "Party" Objects, each containing a Set of UUIDs would make the most sense here. I understand this turns the lookup into a O(n) lookup, but from a data perspective it makes the most sense, as likely you will most often be dealing with the group as a whole. If you're most often doing the other lookup (which party a player is in), then you should do what they said, for simplicity's sake.
    @EndureBlackout
     
  5. Offline

    Lolmewn

    @mythbusterma Muh, it's memory versus CPU cycles. In my opinion CPU cycles always win the argument in such a case.
    Of course.
     
  6. Offline

    ArsenArsen

    Lemme see.. Two things under the same key...
    Heres the code

    public boolean isSameKey(Map map, Object o1, Object o2){
    return false;
    }

    Very fast and simple function.
    </sarcasm>
    Jokes asside, map cannot have two of the same key. Youre better off having a UUID, String map where UUID is the player UUID and String is their party name, or even better, UUID, UUID so you save party UUIDs
     
    MCMastery likes this.
  7. @ArsenArsen *UUID, Set<UUID>
    The user wants multiple people not just 1 in the party :p
     
  8. Offline

    ArsenArsen

    No. PlayerUUID, PartyUUID was my idea.
     
  9. Offline

    MCMastery

    ArsenArsen likes this.
  10. Offline

    mythbusterma

    @Lolmewn

    It's a case of having the data structure that makes the most sense, which is far, far, far more important than a couple hundred cycles.
     
Thread Status:
Not open for further replies.

Share This Page