Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

LinkedCaseInsensitiveMap.keySet().remove returns false after removing a null-valued entry

未关闭 适合新手
#37,470 3 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

  • #37478 来自 @zsewasdsdsd —— 已关闭,未合并

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
78/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
java, spring
领域
backend

调研方向

问题出在 spring-core 中 LinkedCaseInsensitiveMap.java 的内部类 KeySet 里。那里的 remove(o) 根据 Map.remove 是否返回 null 来决定布尔结果,因此值为 null 的条目会返回 false。针对 spring-core 运行 issue 中的 Repro.java 代码片段,确认第一行和第三行输出 false。当 keySet().remove 和 keySet().removeAll 对存在且值为 null 的键返回 true,并且现有的 LinkedCaseInsensitiveMap 测试仍全部通过时,即为完成。

由索引模型根据 Issue 内容生成。

描述

status: waiting-for-triage
Affected versions

Verified with the published spring-core 7.0.9 and 6.2.19 artifacts on JDK 21. The same result was reproduced with the affected classes compiled from main at 85a532dce455655aec8fd5a301b37c6c5ceda5bb, with the remaining dependencies supplied by spring-core 7.0.9. This was a focused reproduction, not a full Gradle build.

Problem

LinkedCaseInsensitiveMap supports null values. When a key is mapped to null, keySet().remove(key) removes the entry but returns false. This contradicts the Set removal contract, and also makes keySet().removeAll(...) report no change when it chooses its remove-based path.

Callers relying on the boolean result to detect a change receive the wrong result even though the map was modified.

Minimal reproduction

Save as Repro.java:

import java.util.Locale;
import java.util.Set;
import org.springframework.util.LinkedCaseInsensitiveMap;

public class Repro {
    public static void main(String[] args) {
        var map = new LinkedCaseInsensitiveMap<String>(Locale.ROOT);
        map.put("key", null);
        System.out.println(map.keySet().remove("key"));
        System.out.println(map.isEmpty());

        map.put("key", null);
        map.put("other", "value");
        System.out.println(map.keySet().removeAll(Set.of("key")));
        System.out.println(map.containsKey("key"));
        System.out.println(map.size());
    }
}

Run on Java 17 or later:

curl -fLO https://repo.maven.apache.org/maven2/org/springframework/spring-core/7.0.9/spring-core-7.0.9.jar
java -cp spring-core-7.0.9.jar Repro.java

Actual output:

false
true
false
false
1

Expected: the first and third lines should be true, because both operations removed an existing key. The remaining lines are correct.

Cause

LinkedCaseInsensitiveMap.KeySet.remove returns LinkedCaseInsensitiveMap.this.remove(o) != null. A null return from Map.remove cannot distinguish an absent key from a present null-valued mapping.

The Java Set.remove contract requires true when the set contained the element and it was removed.

Related reports checked

#22821 / #23644 addressed stale internal key registrations after collection-view removals. This report concerns the boolean return value after a successful removal; the internal key registration is correctly cleared in this reproduction. #37351 concerns computeIfAbsent registrations and is also a separate case. Searches for LinkedCaseInsensitiveMap keySet and LinkedCaseInsensitiveMap null remove did not reveal a direct duplicate.

主要语言
Java
星标
60.3k
派生
38.7k
平均合并
1 天 13 小时
30 天内合并 PR
36

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

spring-projects/spring-framework 的其他 Issue

查看 spring-projects/spring-framework 的全部 Issue

相似的 Issue

更多 Java Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。