chinabugotech/hutool · warning · IllegalArgumentException

Duplicate iterator

Error message

Duplicate iterator

What it means

Thrown by IterChain.addChain(Iterator<T> iterator) when the exact same Iterator instance (by reference equality) is added to the chain more than once. IterChain uses a List.contains() check to prevent duplicate iterator references, which protects against the same iterator being consumed twice during chained traversal.

Source

Thrown at hutool-core/src/main/java/cn/hutool/core/collection/IterChain.java:42

	 */
	public IterChain() {
	}

	/**
	 * 构造
	 * @param iterators 多个{@link Iterator}
	 */
	@SafeVarargs
	public IterChain(Iterator<T>... iterators) {
		for (final Iterator<T> iterator : iterators) {
			addChain(iterator);
		}
	}

	@Override
	public IterChain<T> addChain(Iterator<T> iterator) {
		if (allIterators.contains(iterator)) {
			throw new IllegalArgumentException("Duplicate iterator");
		}
		allIterators.add(iterator);
		return this;
	}

	// ---------------------------------------------------------------- interface

	protected int currentIter = -1;

	@Override
	public boolean hasNext() {
		if (currentIter == -1) {
			currentIter = 0;
		}

		final int size = allIterators.size();
		for (int i = currentIter; i < size; i++) {
			final Iterator<T> iterator = allIterators.get(i);

View on GitHub (pinned to 8870454b2a)

Solutions

  1. Ensure each Iterator added to the chain is a distinct instance.
  2. Call collection.iterator() separately for each position if you need to iterate the same source multiple times.
  3. Deduplicate iterator references before adding them to the chain.

Example fix

// before
Iterator<String> iter = list.iterator();
IterChain<String> chain = new IterChain<>(iter, iter); // throws Duplicate iterator

// after
IterChain<String> chain = new IterChain<>(list.iterator(), list.iterator()); // distinct instances
Defensive patterns

Strategy: validation

Validate before calling

// Deduplicate iterators before adding to chain
Set<Iterator<T>> seen = new HashSet<>();
for (Iterator<T> iter : iterators) {
    if (!seen.contains(iter)) {
        chain.addChain(iter);
        seen.add(iter);
    }
}

Prevention

When it happens

Trigger: Calling iterChain.addChain(sameIterator) twice, or constructing new IterChain(iter1, iter1) with the same iterator reference passed multiple times. The varargs constructor calls addChain for each argument, so passing the same reference twice in the constructor also triggers it.

Common situations: Programmatically building an IterChain in a loop where the same iterator reference is accidentally added twice. Refactoring code that collects iterators into a list without deduplication. Passing the same collection.iterator() result in multiple positions.

Related errors


AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14). Data as JSON: /api/errors/988e62078d0f1c06. Report an issue: GitHub.