Java中如何遍历Map两次后,仅当两次均满足条件时移除元素?
我来帮你搞定这个问题!先说说你当前代码的核心问题:
你现在的逻辑是第一次遍历Calendar元素时,就直接移除不满足当前条件的元素,这会导致第二次遍历的时候,Map里已经是第一次筛选后的结果了——那些第一次就被删掉的元素根本没机会参与第二次判断,完全没法实现「只有两次都满足移除条件才删除」的需求。
正确的思路应该是这样:
先把两次需要判断的条件都确定下来,然后找出那些两次都不匹配条件的元素,最后一次性把这些元素移除,而不是边遍历边删。
修正后的代码:
protected void removeDayOutOfRangeObjects(Map<Object, String> objects, Calendar[] clientTimeRange) { // 先把两次遍历对应的weekdays/weekends都存起来 List<String> requiredParts = new ArrayList<>(); for (Calendar range : clientTimeRange) { int dayOfWeek = range.get(Calendar.DAY_OF_WEEK); requiredParts.add((dayOfWeek == 1 || dayOfWeek == 7) ? "weekends" : "weekdays"); } // 收集所有两次都不匹配的元素key List<Object> keysToRemove = new ArrayList<>(); for (Map.Entry<Object, String> entry : objects.entrySet()) { String value = entry.getValue(); // 判断:既不匹配第一个条件,也不匹配第二个条件 boolean failsFirstCheck = !value.matches(requiredParts.get(0)); boolean failsSecondCheck = !value.matches(requiredParts.get(1)); if (failsFirstCheck && failsSecondCheck) { keysToRemove.add(entry.getKey()); } } // 统一移除符合条件的元素 keysToRemove.forEach(objects::remove); }
几点补充说明:
- 关于
matches方法:如果你的entry.getValue()是直接等于"weekdays"或"weekends"(不是正则匹配场景),建议把matches换成equals,性能会更好,比如:boolean failsFirstCheck = !requiredParts.get(0).equals(value); boolean failsSecondCheck = !requiredParts.get(1).equals(value); - 为什么要先收集再移除:如果在遍历Map的时候直接修改(移除元素),很容易触发
ConcurrentModificationException,先收集所有要删的key再统一处理是更安全的做法。 - 逻辑验证:只有当元素在第一次判断不匹配,并且第二次判断也不匹配的时候,才会被加入移除列表,完全符合你「两次都满足移除条件才删除」的需求。
内容的提问来源于stack exchange,提问作者OneXer
相关产品推荐
相关产品推荐

