获取并发修改异常

Getting Concurrent Modification Exception

我不知道为什么会收到此错误: error message

这是第 107 行(for 循环):

        for (Pair<UUID, UUID> pair : timeStopList) {

           if (pair.getA() == playerUUID) {

              cancelTimeStop(pair.getB());

           }

        }

我不想问看似如此简单的解决方案,但我真的不知道发生了什么!如果您知道答案,请告诉我,我将不胜感激。谢谢!

取消时间停止代码:

    public static void cancelTimeStop(UUID entityUUID) {

    Entity unknownEntity = Bukkit.getEntity(entityUUID);

    if (unknownEntity == null || unknownEntity.isDead()) return;

    LivingEntity entity = (LivingEntity) unknownEntity;

    entity.removePotionEffect(PotionEffectType.SLOW);
    entity.removePotionEffect(PotionEffectType.BLINDNESS);

    entity.setGravity(true);
    entity.setAI(true);
    entity.setCanPickupItems(true);
    entity.setSilent(false);

    removeEntityFromTimeStop(entityUUID);

}

removeEntityFromTimeStop() 是:

    private static void removeEntityFromTimeStop(UUID entityUUID) {

    if (timeStopList == null) return;

    timeStopList.removeIf(pair -> pair.getB() == entityUUID);

}

您可以稍微更改 for loop 以避免此异常:

Pair<UUID, UUID> pairToRemove = null;
for (Pair<UUID, UUID> pair : timeStopList) {
    if (pair.getA() == playerUUID) {
        pairToRemove = pair; // assign the found pair to pairToRemove variable
        break;
    }
}
if (pairToRemove != null) {
    cancelTimeStop(pairToRemove.getB());
}

更新

P.S。我假设一旦找到 pair.getA() == playerUUID 就没有必要继续循环。如果此 if 语句的计算结果有多个机会 true 那么您可以将代码调整为:

List<Pair<UUID, UUID>> pairToRemoveList = new ArrayList();
for (Pair<UUID, UUID> pair : timeStopList) {
    if (pair.getA() == playerUUID) {
        pairToRemoveList.add(pair);
    }
}
if (!pairToRemoveList.isEmpty()) {
    for (Pair<UUID, UUID> pair : pairToRemoveList) {
        cancelTimeStop(pair.getB());
    }
}

迭代集合并从中删除项目时抛出并发修改异常。在这种情况下,Pair<UUID, UUID>timeStopList

中删除
timeStopList.removeIf(pair -> pair.getB() == entityUUID);

解决方案是在迭代时必须删除列表并且不需要对您的逻辑进行其他修改时使用迭代器:

Iterator<Pair<UUID, UUID>> iter = cancelTimeStop.listIterator();
while(iter.hasNext()){
    if(...){
        iter.remove();
    }
}