You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java按HashMap键值过滤二维数组 筛选指定数量候选人问题排查

问题排查与修复

核心Bug根因

筛选候选人的逻辑错误使用了while循环,导致单个候选人会重复占用同岗位的所有剩余名额:

  • 业务逻辑上单个候选人最多只能占对应岗位1个招聘名额,匹配到岗位且有剩余名额时,只需要做1次判断、扣减1次名额即可,不需要循环
  • 现有while逻辑下,遇到第一个匹配岗位且有剩余名额的候选人时,会反复进入循环:虽然Set会自动去重不会重复存储人名,但AtomicInteger的计数会被持续递减,直接把该岗位的剩余名额全扣在这一个候选人身上,后续同岗位符合要求的候选人自然没有名额可选。

以第二组测试用例为例,developer岗招聘2人,遍历到第一个developer岗候选人Bill时:

  1. 第一次进循环:添加Bill到结果集,名额从2减到1,此时循环条件依然满足(岗位匹配、剩余名额1>0)
  2. 第二次进循环:Bill已经在Set中不会重复添加,但名额还是会被减到0,直接把2个名额全用完,后续排序靠后的John自然不会被选中。

其他可优化问题

  • 内层循环遍历全量Map entry匹配岗位效率极低:每个候选人只对应一个应聘岗位,直接通过岗位key从Map中取剩余名额即可,不需要遍历所有岗位,时间复杂度可以从O(m*n)降到O(m)(m为候选人数,n为岗位数)
  • 使用TreeSet存储结果会默认按姓名字典序排序,和实际录取优先级无关,如果业务要求按录取优先级输出,应该替换为LinkedHashSet按插入顺序存储。

修复后的核心筛选逻辑

把原来的双层循环+while的逻辑替换为以下代码即可:

// 用LinkedHashSet保留录取顺序,更符合招聘场景的输出要求
Set<String> res = new LinkedHashSet<>();
for (String[] candidate : candidates) {
    String applyPost = candidate[1];
    AtomicInteger remainCount = hm.get(applyPost);
    // 单个候选人只做一次判断,不需要循环
    if (remainCount != null && remainCount.get() > 0) {
        res.add(candidate[0]);
        remainCount.decrementAndGet();
    }
}

结果验证

  • 第一组测试用例(developer招1、project招1):排序后按优先级依次录取Bill(占用developer名额)、Steve(占用project名额),输出[Bill, Steve]符合预期
  • 第二组测试用例(developer招2、project招1):依次录取Bill(developer剩余1个名额)、Steve(project名额用完)、John(developer剩余名额用完),输出[Bill, John, Steve]符合预期

内容的提问来源于stack exchange,提问作者PRD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 07:42:28