{"record":{"id":"988e62078d0f1c06","repo":"chinabugotech/hutool","slug":"duplicate-iterator","errorCode":null,"errorMessage":"Duplicate iterator","messagePattern":"Duplicate iterator","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"warning","filePath":"hutool-core/src/main/java/cn/hutool/core/collection/IterChain.java","lineNumber":42,"sourceCode":"\t */\n\tpublic IterChain() {\n\t}\n\n\t/**\n\t * 构造\n\t * @param iterators 多个{@link Iterator}\n\t */\n\t@SafeVarargs\n\tpublic IterChain(Iterator<T>... iterators) {\n\t\tfor (final Iterator<T> iterator : iterators) {\n\t\t\taddChain(iterator);\n\t\t}\n\t}\n\n\t@Override\n\tpublic IterChain<T> addChain(Iterator<T> iterator) {\n\t\tif (allIterators.contains(iterator)) {\n\t\t\tthrow new IllegalArgumentException(\"Duplicate iterator\");\n\t\t}\n\t\tallIterators.add(iterator);\n\t\treturn this;\n\t}\n\n\t// ---------------------------------------------------------------- interface\n\n\tprotected int currentIter = -1;\n\n\t@Override\n\tpublic boolean hasNext() {\n\t\tif (currentIter == -1) {\n\t\t\tcurrentIter = 0;\n\t\t}\n\n\t\tfinal int size = allIterators.size();\n\t\tfor (int i = currentIter; i < size; i++) {\n\t\t\tfinal Iterator<T> iterator = allIterators.get(i);","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/chinabugotech/hutool/blob/8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442/hutool-core/src/main/java/cn/hutool/core/collection/IterChain.java#L24-L60","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure each Iterator added to the chain is a distinct instance.","Call collection.iterator() separately for each position if you need to iterate the same source multiple times.","Deduplicate iterator references before adding them to the chain."],"exampleFix":"// before\nIterator<String> iter = list.iterator();\nIterChain<String> chain = new IterChain<>(iter, iter); // throws Duplicate iterator\n\n// after\nIterChain<String> chain = new IterChain<>(list.iterator(), list.iterator()); // distinct instances","handlingStrategy":"validation","validationCode":"// Deduplicate iterators before adding to chain\nSet<Iterator<T>> seen = new HashSet<>();\nfor (Iterator<T> iter : iterators) {\n    if (!seen.contains(iter)) {\n        chain.addChain(iter);\n        seen.add(iter);\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Call collection.iterator() separately for each chain position.","Deduplicate iterator references before adding to IterChain.","Avoid reusing the same iterator variable across addChain() calls."],"tags":["collection","iterator","duplicate","chain"],"backgroundTag":null,"analyzedSha":"8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442","analyzedAt":"2026-08-14T04:01:12.892Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}