Solved Iterating through a Hashmap doesn't work

Discussion in 'Plugin Help/Development/Requests' started by Smootey, Apr 2, 2015.

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

    Smootey

    Hello guys,

    I've been trying to iterate through a hashmap and remove the entry, but it prints me an error.
    ResetListener Class:

    ResetListener Class (open)

    Code:
    package de.smoothie2.prison.scheduler;
    
    import java.util.Iterator;
    import java.util.Map.Entry;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.Material;
    
    import de.smoothie2.prison.events.BlockListener;
    import de.smoothie2.prison.main.Main;
    
    public class ResetScheduler {
        private static int scheduler;
        private static int i;
        private static boolean isresetting = false;
        public static void start() {
            scheduler = Bukkit.getScheduler().scheduleSyncRepeatingTask(Main.getInstance(), new Runnable() {
                public void run() {
                    Bukkit.broadcastMessage("\u00a7bEs werden nun alle \u00a73Minen \u00a7bzurückgesetzt.");
                    i = Bukkit.getScheduler().scheduleSyncRepeatingTask(Main.getInstance(), new Runnable() {
                        public void run() {
                            isresetting = true;
                            int c = 0;
                            Iterator<Entry<Location, Material>> it = BlockListener.getBrokenBlocks().entrySet().iterator();
                            while(it.hasNext() && c < 10000) {
                                Entry<Location, Material> map = it.next();
                                map.getKey().getWorld().getBlockAt(map.getKey()).setType(map.getValue());
                                BlockListener.getBrokenBlocks().remove(map.getKey());
                                c++;
                            }
                        }
                    }, 0, 20);
                    Bukkit.getScheduler().scheduleSyncDelayedTask(Main.getInstance(), new Runnable() {
                        public void run() {
                            Bukkit.getScheduler().cancelTask(i);
                            i = 0;
                            isresetting = false;
                            Bukkit.broadcastMessage("\u00a7bEs wurden erfolgreich alle \u00a73Minen \u00a7bzurückgesetzt.");
                        }
                    }, (Math.round(BlockListener.getBrokenBlocks().size()/10000)+1)*20);
                }
            }, 6000, 6000);
        }
        public static void stop() {
            if(scheduler != 0) Bukkit.getScheduler().cancelTask(scheduler);
            scheduler = 0;
        }
        public static boolean isResetting() {
            return isresetting;
        }
    }
    


    And the error:

    Error (open)

    Code:
    [17:30:52 WARN]: [Prison] Task #12 for Prison v0.1_SNAPSHOT generated an excepti
    on
    java.util.ConcurrentModificationException
            at java.util.HashMap$HashIterator.nextNode(Unknown Source) ~[?:1.8.0_25]
    
            at java.util.HashMap$EntryIterator.next(Unknown Source) ~[?:1.8.0_25]
            at java.util.HashMap$EntryIterator.next(Unknown Source) ~[?:1.8.0_25]
            at de.smoothie2.prison.scheduler.ResetScheduler$1$1.run(ResetScheduler.j
    ava:27) ~[?:?]
            at org.bukkit.craftbukkit.v1_8_R1.scheduler.CraftTask.run(CraftTask.java
    :71) ~[spigot.jar:git-Spigot-ed3e3af-ee6d0fa]
            at org.bukkit.craftbukkit.v1_8_R1.scheduler.CraftScheduler.mainThreadHea
    rtbeat(CraftScheduler.java:350) [spigot.jar:git-Spigot-ed3e3af-ee6d0fa]
            at net.minecraft.server.v1_8_R1.MinecraftServer.z(MinecraftServer.java:7
    09) [spigot.jar:git-Spigot-ed3e3af-ee6d0fa]
            at net.minecraft.server.v1_8_R1.DedicatedServer.z(DedicatedServer.java:3
    16) [spigot.jar:git-Spigot-ed3e3af-ee6d0fa]
            at net.minecraft.server.v1_8_R1.MinecraftServer.y(MinecraftServer.java:6
    34) [spigot.jar:git-Spigot-ed3e3af-ee6d0fa]
            at net.minecraft.server.v1_8_R1.MinecraftServer.run(MinecraftServer.java
    :537) [spigot.jar:git-Spigot-ed3e3af-ee6d0fa]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_25]


    Thanks for your help,
    Smootey ~
     
  2. Offline

    bwfcwalshy Retired Staff

    Moved to Bukkit Alternates.
     
  3. Offline

    pie_flavor

    @Smootey Why use a while loop? You can use a for loop on an array or iterable.
    Also, the rest of the code would be appreciated as I have no idea what any of those referenced classes (Entry, BlockListener, etc.) look like.
     
  4. Offline

    Smootey

    @pie_flavor I need to use a while loop so I can delete the entry from the Hashmap while looping. The Entry Object is from Java itself, the BlockListener.getBrokenBlocks() is a new HashMap<Location, Material>();. I hope that helps!
     
  5. Offline

    pie_flavor

    @Smootey
    Code:
    for (Location loc : BlockListener.getBrokenBlocks().keySet()) {
        Material m = BlockListener.getBrokenBlocks().get(loc);
        //derp de derp derp durr
        BlockListener.getBrokenBlocks().remove(loc);
    }
     
  6. Offline

    Smootey

    @pie_flavor If you would've tested it, you would've noticed, that this is not working, because you can't delete an Entry while looping the Hashmap.

    Edit: Got it working by myself - just do
    Code:
    it.remove();
     
  7. Offline

    pie_flavor

    @Smootey Got it. You can actually delete an entry while looping.
    What you can't do is delete an entry inside a subthread, i.e. BukkitRunnable.
     
    Smootey likes this.
Thread Status:
Not open for further replies.

Share This Page