哈希表 getcontainsKey 不起作用

HashTable getcontainsKey does not work

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

我的 class 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;
}

你能解释一下为什么吗?

谢谢

你需要在运行ning hasAccessToWebservice

之前调用updatePermissions将所有数据放入你的权限中

如果您 运行 hasAccessToWebservice 没有 updatePermissions,则权限列表中没有任何内容 => this.permissions.containsKey(key) 无效

问题总结

总结一下题目,问题围绕着关键的一致性:

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

    Returns a hash code for this string. The hash code for a String object is computed as

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

    using int arithmetic, where s[i] is the ith character of the string, n is the length of the string, and ^ indicates exponentiation. (The hash value of the empty string is zero.)

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

解决方案/改进

  • 最简单的解决方案是确保 createKeyPermissions 方法始终生成一致的密钥,方法是将所有内容都小写
  • 使用 TreeMap with a comparator where the most fitted one is String.CASE_INSENSITIVE_ORDER