【问题标题】:HashTable getcontainsKey does not workHashTable getcontainsKey 不起作用
【发布时间】:2017-10-05 15:57:12
【问题描述】:

我不明白为什么这个简单的方法不起作用

我的班级AccessChecker 具有Hashtable<String, List<Permission>> permissions = new Hashtable<String, List<Permission>>(); 属性,有两种方法:

第一种方法

如果我把this.permissions.containsKey(key)放在这个方法的最后,用一个好的键,它就可以工作。

public void updatePermissions() {
    List<Permission> permissionsTmp = permissionRepository.findAllWithEagerRelationships();

    // clear permissions
    this.permissions = new Hashtable<>();

    // load all permissions
    for (Permission permission : permissionsTmp) {
        Profil profil = profilRepository.findOne(permission.getProfil().getId());
        permission.setProfil(profil);
        UserFonc user = userFoncRepository.findOne(permission.getUserFonc().getId());
        permission.setUserFonc(user);

        log.error("updatePermissions ** user login = " + user.getNom());

        for (WebService webService: profil.getWebServices()) {
            String key = createKeyPermissions(user.getNom().toLowerCase(), webService.getNom(), webService.getMethode());
            log.error("updatePermissions ** key = " + key);
            if (this.permissions.containsKey(key)){
                this.permissions.get(key).add(permission);
            }
            else {
                List<Permission> newPermissions = new ArrayList<>();
                newPermissions.add(permission);
                this.permissions.put(key, newPermissions);
            }

        }
    }
}

第二种方法

但是,当我在方法hasAccessToWebservice() 中执行此操作时,它不适用于同一个键...

public boolean hasAccessToWebservice(HttpServletRequest request) {
    boolean hasAccess = false;

    String webservice = getServiceFromRequest(request);
    String methode = request.getMethod();
    String login = SecurityUtils.getCurrentUserLogin();
    String userAgent = request.getHeader(Constants.USER_AGENT);

    final String userLogin = SecurityUtils.getCurrentUserLogin();
    log.error("hasAccessToWebservice ** user login = " + userLogin);

    String key = createKeyPermissions(login.toLowerCase(), webservice, methode);
    log.error("hasAccessToWebservice ** key = " + key);

    log.error("hasAccessToWebservice ** element = " + this.permissions.size());

    Set t = this.permissions.keySet();
    log.error(t.toString());

    if (this.permissions.containsKey(key)) {
        log.error("hasAccessToWebservice ** key found !!");
        hasAccess = true;
    }
    return hasAccess;
}

你能解释一下原因吗?

谢谢

【问题讨论】:

  • 什么不起作用?您是否有错误或只是您希望有 containsKey(...) == true 并且它是错误的?
  • containsKey 总是返回 false,但是当我在 HashTable 上执行 toString 时,我看到了我的密钥
  • 你介意举一个数据的例子,因为它让我想到this吗?该链接还提到Hashtable 已过时,如果可以,请切换到HashMap。与问题无关,但我看到您在log.error 中记录了所有内容,但看起来更像infodebug
  • 我用 HashMap 替换 Hashtable 但结果相同。在我的日志中,我看到我搜索 keey "adminvannesSetBonSAVPOST" 并且我的 HashMap 包含此密钥 (HashMap.keySet().toString()):[admin lorientSetBonSavPOST, adminvannesGetBonSavGET, admin lorientDeleteBonSavDELETE, adminvannesSetBonSavPOST, swaroskyGetBonSavGET, admin lorientGetBonSavGET, admin
  • 更改为HashMap 会神奇地解决您的问题,而是为了保持最新状态。 adminvannesSetBonSAVPOSTSAVadmanvannesSetBonSavPOSTSav 是否正常? String.equals() is case sensitive

标签: java hashtable containskey


【解决方案1】:

问题总结

总结主题,问题围绕关键一致性:

  1. Map.containsKey(Object key) 基本上会检查key 是否在Map.keySet() 中,主要依靠Object.hashCode()
  2. 您的地图键类是String。如果您查看String.hashCode() 代码,您会发现它依赖于每个单个字符值。

    返回此字符串的哈希码。 String 对象的哈希码计算为

    s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

    使用int算术,其中s[i]是字符串的第i个字符,n是字符串的长度,^表示求幂。 (空字符串的哈希值为零。)

    值可以在ASCII Table 中找到,突出显示hashCode() 区分大小写

解决方案/改进

  • 最简单的解决方案是确保createKeyPermissions 方法始终生成一致的密钥,因为接口将所有内容都放在小写中
  • TreeMap 与比较器一起使用,其中最适合的比较器是String.CASE_INSENSITIVE_ORDER

【讨论】:

    【解决方案2】:

    在运行hasAccessToWebservice之前需要调用updatePermissions将所有数据放入你的权限中

    如果您在没有 updatePermissions 的情况下运行 hasAccessToWebservice,则权限列表中没有任何内容 => this.permissions.containsKey(key) 不起作用

    【讨论】:

    • updatePermissions 是在启动应用程序时调用并包含数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-30
    • 2021-02-25
    • 2011-06-05
    • 2016-02-22
    • 2012-04-26
    • 1970-01-01
    • 2011-03-27
    相关资源
    最近更新 更多