Getting Entry from an hashmap

Discussion in 'Plugin Development' started by ThrustLP, May 23, 2016.

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

    ThrustLP

    Hey guys! I have got an Hashmap:

    Code:
    public HashMap<String, String> motds = new HashMap<String, String>();
    and I add the folowing things to it:

    Code:
    motds.put("one", "1");
            motds.put("two", "2");
            motds.put("three", "3");
    Now I have an Scheduler that writes every object of the HashMap in the chat (write->wait some ticks.->write...), no matter in what order.

    Code:
    public void time(){
           
           
           
            Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable(){
                int t = 1;
               
               
               
                public void run(){
                    if(t == motds.size()){
                        String s = motds.values().toArray()[motds.size()].toString();
                        Bukkit.getServer().broadcastMessage(s);
                        t = 1;
                       
                    }else{
                        String s = motds.values().toArray()[t].toString();
                        Bukkit.getServer().broadcastMessage(s);
                        t++;
                       
                    }
                   
                   
                }
               
               
            }, 40, 20*intcfg);
        }
    Everything works fine, and it writes the first two entrys in the chat. But as soon as it reaches the if(t == motds.size()) I get the following error in the console:

    Code:
    [17:14:42 WARN]: [CUNNotify] Task #1801 for CUNNotify va0.1 generated an exception
    java.lang.ArrayIndexOutOfBoundsException: 3
            at me.thruzzd.cunnotice.Main$1.run(Main.java:63) ~[?:?]
            at org.bukkit.craftbukkit.v1_9_R1.scheduler.CraftTask.run(CraftTask.java:71) ~[spigot_server.jar:git-Spigot-2038f4a-cd36f6f]
            at org.bukkit.craftbukkit.v1_9_R1.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:350) [spigot_server.jar:git-Spigot-2038f4a-cd36f6f]
            at net.minecraft.server.v1_9_R1.MinecraftServer.D(MinecraftServer.java:729) [spigot_server.jar:git-Spigot-2038f4a-cd36f6f]
            at net.minecraft.server.v1_9_R1.DedicatedServer.D(DedicatedServer.java:400) [spigot_server.jar:git-Spigot-2038f4a-cd36f6f]
            at net.minecraft.server.v1_9_R1.MinecraftServer.C(MinecraftServer.java:660) [spigot_server.jar:git-Spigot-2038f4a-cd36f6f]
            at net.minecraft.server.v1_9_R1.MinecraftServer.run(MinecraftServer.java:559) [spigot_server.jar:git-Spigot-2038f4a-cd36f6f]
            at java.lang.Thread.run(Unknown Source) [?:1.7.0_79]
    Why? And how can I fix it?

    Thanks!
     
  2. Here is an example array with a size of 3:
    { object 1, object 2, object 3 }

    How to access it:
    array[0] array[1] array[2]

    Notice something? There is no array[3] because that would be the 4th element (doesn't exist -> error).

    Use ++t mixed with remainder operator (%). That ensures that if the index t is bigger than the Collection's size, it begins from 0 again.

    Example:
    Code:
    int i = 0;
    while (1) {
        System.out.print(i + ", ");
        i = ++i %3;
    }
    Output: 0, 1, 2, 0, 1, 2, etc...
    Why ++i and not i++ ? Here's the answer

    @Zombie_Striker A even more efficent way to achieve what you want is the following :p:
    Code:
    int t = 0;
    
    public void run() {
       String s = motds.values().toArray()[t].toString();
       Bukkit.broadcastMessage(s);
       t = ++t %motds.size();
    }
    Comparison to original code inside run(): 13 lines. My code: 3 lines

    Why do you use Bukkit.getServer().method() ? Useless. Bukkit.method() is the same.
     
    Last edited: May 23, 2016
  3. Offline

    Zombie_Striker

    @ThrustLP
    That is because you forgot .size != the last indxed. The method ".size()" returns the index +1, because it's first value is 1, while the first value for the index is 0.

    To fix this, don't even check if it is equal to the size. A more efficent way to achieve what you want is the following:
    Code:
    int t = 0; //IT MUST BE 0, BECAUSE THE FIRST INDEX IS 0.        
    
    public void run(){
     if(t == motds.size()){
      //If t is out of bounds
      t=0;//Set it back to 0.
    }
    String s = motds.values().toArray()[t].toString();
    Bukkit.getServer().broadcastMessage(s);
    t++;  
    }
     
Thread Status:
Not open for further replies.

Share This Page