chinabugotech/hutool · error · UnsupportedOperationException
Cache values Iterator is not support to modify.
Error message
Cache values Iterator is not support to modify.
What it means
CacheObjIterator.remove() is intentionally unimplemented — the underlying cache does not support removing entries through its value iterator, so it throws UnsupportedOperationException. Hutool's cache iterator is read-only by design; mutation must go through the cache's own remove/evict API. Calling remove() on either the entry iterator or the value iterator derived from a CacheImpl will hit this.
Source
Thrown at hutool-cache/src/main/java/cn/hutool/cache/impl/CacheObjIterator.java:58
/**
* @return 下一个值
*/
@Override
public CacheObj<K, V> next() {
if (false == hasNext()) {
throw new NoSuchElementException();
}
final CacheObj<K, V> cachedObject = nextValue;
nextValue();
return cachedObject;
}
/**
* 从缓存中移除没有过期的当前值,此方法不支持
*/
@Override
public void remove() {
throw new UnsupportedOperationException("Cache values Iterator is not support to modify.");
}
/**
* 下一个值,当不存在则下一个值为null
*/
private void nextValue() {
while (iterator.hasNext()) {
nextValue = iterator.next();
if (nextValue.isExpired() == false) {
return;
}
}
nextValue = null;
}
}
View on GitHub (pinned to 8870454b2a)
Solutions
- Do not call remove() on the iterator; collect keys and remove them via Cache.remove(key) after iteration.
- Use cache.clear() or cache.prune() to evict rather than iterator mutation.
- If building a derived collection, copy entries into a new Map/List first, then mutate that.
Example fix
// before
Iterator<CacheObj<K,V>> it = cache.iterator();
while (it.hasNext()) { if (stale(it.next())) it.remove(); }
// after
List<K> toRemove = new ArrayList<>();
cache.forEach(it2 -> { if (stale(it2)) toRemove.add(it2.getKey()); });
toRemove.forEach(cache::remove); Defensive patterns
Strategy: validation
Validate before calling
// never call iterator.remove() on a cache iterator; collect keys first
List<K> keys = new ArrayList<>();
cache.iterator().forEachRemaining(o -> { if (stale(o)) keys.add(o.getKey()); });
keys.forEach(cache::remove); Try / catch
try { it.remove(); } catch (UnsupportedOperationException e) { /* use cache.remove(key) instead */ } Prevention
- Treat all hutool cache iterators as read-only.
- Prefer cache.remove(key) / cache.prune() for eviction.
When it happens
Trigger: Obtaining an iterator via cache.iterator(), cacheCacheObj.values().iterator(), or similar, then calling .remove() on it (often from enhanced-for loops that use Iterator.remove, or copy-by-filter utilities that mutate during iteration).
Common situations: Using Java streams/loops that expect a mutable iterator; writing a filter-and-prune routine against the cache directly instead of the cache API; porting code from a Map-based implementation.
Related errors
- remove() method not supported for a NodeListIterator.
- proxied annotation can not reset attributes
- Duplicate iterator
- Unsupport Reference type: {}
AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14).
Data as JSON: /api/errors/362fd4d6cfb707c6.
Report an issue: GitHub.