{"record":{"id":"dc0f2d5f63d5c20a","repo":"apache/dubbo","slug":"the-map-value-must-be-unique","errorCode":null,"errorMessage":"The map value must be unique.","messagePattern":"The map value must be unique\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/utils/CollectionUtils.java","lineNumber":100,"sourceCode":"        return list;\n    }\n\n    /**\n     * Flip the specified {@link Map}\n     *\n     * @param map The specified {@link Map},Its value must be unique\n     * @param <K> The key type of specified {@link Map}\n     * @param <V> The value type of specified {@link Map}\n     * @return {@link Map}\n     */\n    @SuppressWarnings(\"unchecked\")\n    public static <K, V> Map<V, K> flip(Map<K, V> map) {\n        if (isEmptyMap(map)) {\n            return (Map<V, K>) map;\n        }\n        Set<V> set = new HashSet<>(map.values());\n        if (set.size() != map.size()) {\n            throw new IllegalArgumentException(\"The map value must be unique.\");\n        }\n        return map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));\n    }\n\n    public static Map<String, Map<String, String>> splitAll(Map<String, List<String>> list, String separator) {\n        if (list == null) {\n            return null;\n        }\n        Map<String, Map<String, String>> result = new HashMap<>();\n        for (Map.Entry<String, List<String>> entry : list.entrySet()) {\n            result.put(entry.getKey(), split(entry.getValue(), separator));\n        }\n        return result;\n    }\n\n    public static Map<String, List<String>> joinAll(Map<String, Map<String, String>> map, String separator) {\n        if (map == null) {\n            return null;","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/CollectionUtils.java#L82-L118","documentation":"Thrown by CollectionUtils.flip when the source map has duplicate values. flip() reverses keys and values to produce Map<V,K>; if two keys share the same value, the reversal would silently lose an entry, so the method detects non-unique values (set size < map size) and refuses rather than corrupting data.","triggerScenarios":"CollectionUtils.flip(map) where map.values() contains duplicates — i.e. two or more distinct keys map to equal values. The guard compares new HashSet<>(map.values()).size() to map.size().","commonSituations":"Inverting a lookup index (id->name) to (name->id) when names are not unique; flipping a config map where two config keys share a value; flipping a reverse-lookup that legitimately has collisions. The caller must decide which key wins or restructure the data.","solutions":["Deduplicate or disambiguate values before flipping (append a suffix, or keep Map<K, List<V>> via groupingBy).","If collisions are expected, use a multi-valued flip: map.entrySet().stream().collect(groupingBy(Map.Entry::getValue, mapping(Map.Entry::getKey, toList()))).","Verify the source data really should have unique values; fix the upstream producer if duplicates are a data bug."],"exampleFix":"// before\nMap<String,String> m = Map.of(\"a\",\"x\", \"b\",\"x\");\nCollectionUtils.flip(m); // throws: 'x' appears twice\n\n// after (multi-valued)\nMap<String,List<String>> flipped = m.entrySet().stream()\n    .collect(Collectors.groupingBy(Map.Entry::getValue,\n        Collectors.mapping(Map.Entry::getKey, Collectors.toList())));","handlingStrategy":"validation","validationCode":"Map<String,String> map = /* ... */;\nint distinct = new HashSet<>(map.values()).size();\nif (distinct != map.size()) {\n    // duplicate values present; use a multi-valued flip instead\n}\nCollectionUtils.flip(map);","typeGuard":"static <K,V> boolean hasUniqueValues(Map<K,V> map) {\n    return new HashSet<>(map.values()).size() == map.size();\n}","tryCatchPattern":null,"preventionTips":["Check value uniqueness before flipping, or use groupingBy for a multi-valued reverse map.","Disambiguate duplicate values upstream if a 1:1 flip is required.","Document which side is authoritative when names map to multiple ids."],"tags":["collections","map","validation"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}