Juergen Hoeller opened SPR-16926 and commented

Explicit implementations of putIfAbsent and computeIfAbsent allow for reusing the converted key within those steps. Also, both variants should return the old value (if any) even for a differently cased key; this also needs to be revised in the regular put implementation.


Issue Links: - #12624 LinkedCaseInsensitiveMap does not correctly implement putAll() - #18553 LinkedCaseInsensitiveMap doesn't implement getOrDefault properly - #21120 JdbcTemplate.queryForMap should return first value of equally named columns

Comment From: metaruslan

Is it a bug that java.util.Map#putIfAbsent does not honor the case where the key is associated with a null value. Here is the javadoc inherited from java.util.Map

If the specified key is not already associated with a value (or is mapped to null) associates it with the given value and returns null, else returns the current value.

Here is the code showing the difference with the normal map:

        Map<String, String> normalMap = new HashMap<>();
        Map<String, String> caseInsensitiveMap = new LinkedCaseInsensitiveMap<>();
        normalMap.put("key", null);
        System.out.println("normal map:" + normalMap);
        normalMap.putIfAbsent("key", "value");
        System.out.println("normal map:" + normalMap);

        caseInsensitiveMap.put("key", null);
        System.out.println("case insensitive map" + caseInsensitiveMap);
        caseInsensitiveMap.putIfAbsent("key", "value");
        System.out.println("case insensitive map" + caseInsensitiveMap);

Output: normal map:{key=null} normal map:{key=value} case insensitive map{key=null} case insensitive map{key=null}

According to the javadoc it should return null and make the change, but the code only returns null, the line: return this.targetMap.get(oldKey) The implementation

        @Override
    @Nullable
    public V putIfAbsent(String key, @Nullable V value) {
        String oldKey = this.caseInsensitiveKeys.putIfAbsent(convertKey(key), key);
        if (oldKey != null) {
            return this.targetMap.get(oldKey);
        }
        return this.targetMap.putIfAbsent(key, value);
    }

Comment From: sbrannen

@metaruslan, this issue was closed almost 3 years ago.

If you think you have discovered a bug against a recent version of the Spring Framework, please open a new issue to describe it.

Thanks

Comment From: metaruslan

Done https://github.com/spring-projects/spring-framework/issues/26868

Thanks!