You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Minecraft Java插件:如何移除HashMap中存储的所有方块

搞定方块清理:遍历HashMap销毁存储的方块

没问题,我来帮你解决这个遍历HashMap销毁方块的问题。咱们一步步来:

核心逻辑:安全遍历并清理方块

因为你在遍历过程中要移除HashMap里的元素,直接遍历原集合会触发并发修改异常,所以得用安全的遍历方式。这里给你两种靠谱的写法:

方法一:用迭代器遍历(最安全)

迭代器专门处理遍历中修改集合的场景,不会出问题:

// 先写一个通用的重置方法,方便复用
public void resetAllStoredBlocks() {
    // 获取HashMap的条目迭代器
    Iterator<Map.Entry<Block, Location>> iterator = BlockReset.entrySet().iterator();
    
    while (iterator.hasNext()) {
        Map.Entry<Block, Location> entry = iterator.next();
        Block targetBlock = entry.getKey();
        
        // 把方块改成空气就是销毁了
        targetBlock.setType(Material.AIR);
        
        // 用迭代器移除条目,避免并发修改异常
        iterator.remove();
    }
}

方法二:遍历集合的副本(更简洁)

如果觉得迭代器麻烦,也可以把HashMap的键转成新的List,这样遍历副本时修改原HashMap不会影响遍历:

public void resetAllStoredBlocks() {
    // 转成新的ArrayList,隔离原集合
    List<Block> blocksToRemove = new ArrayList<>(BlockReset.keySet());
    
    for (Block block : blocksToRemove) {
        block.setType(Material.AIR);
        BlockReset.remove(block);
    }
}

绑定到resetblocks命令

接下来把这个方法绑到你的命令上,比如用CommandExecutor

public class ResetBlocksCmd implements CommandExecutor {
    private YourPluginMain plugin;

    // 构造方法传入主类实例
    public ResetBlocksCmd(YourPluginMain plugin) {
        this.plugin = plugin;
    }

    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
        if (!cmd.getName().equalsIgnoreCase("resetblocks")) {
            return false;
        }
        
        // 调用重置方法
        plugin.resetAllStoredBlocks();
        sender.sendMessage("所有存储的方块已经清理完毕!");
        return true;
    }
}

记得在你的主类里注册这个命令:

@Override
public void onEnable() {
    this.getCommand("resetblocks").setExecutor(new ResetBlocksCmd(this));
}

绑定到游戏停止/插件卸载事件

要在游戏停止或者插件卸载时自动清理,监听DisableEvent就行(这个事件在插件卸载、服务器停止时都会触发,覆盖场景更全):

// 这个方法要放在你的事件监听器类里,记得注册监听器哦
@EventHandler
public void onPluginShutdown(DisableEvent event) {
    resetAllStoredBlocks();
}

小建议:优化存储方式

其实你现在用HashMap<Block, Location>有点多余——Block本身就能获取到Location,而且Block对象在世界卸载后会失效,换成直接存Location更稳定:

// 改成HashSet存储Location就行,不需要HashMap
public HashSet<Location> storedBlocks = new HashSet<>();

// 放置方块时添加
public void onPlace(BlockPlaceEvent event) {
    Block block = event.getBlock();
    storedBlocks.add(block.getLocation());
}

// 重置时的代码
public void resetAllStoredBlocks() {
    for (Location loc : new ArrayList<>(storedBlocks)) {
        loc.getBlock().setType(Material.AIR);
        storedBlocks.remove(loc);
    }
}

这样能避免因为世界加载问题导致方块无法正常清理的情况。

内容的提问来源于stack exchange,提问作者EssemCSH

火山引擎 最新活动