HashTable getcontainsKey不起作用

时间:2017-10-05 15:57:12

标签: java hashtable containskey

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

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

你能解释一下原因吗?

谢谢

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

问题摘要

总结该主题,问题围绕密钥一致性:

  1. Map.containsKey(Object key)基本上会依赖key
  2. 检查Map.keySet()是否属于Object.hashCode()
  3. 您的地图密钥类为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()区分大小写

  4. 解决方案/改进

    • 最简单的解决方案是确保createKeyPermissions方法始终生成一致的密钥,以便将所有内容都设置为小写
    • 使用带有比较器的TreeMap,其中最适合的比较器为String.CASE_INSENSITIVE_ORDER