Java 基于散列的HashMap密钥生成

Java 基于散列的HashMap密钥生成,java,hash,Java,Hash,我的意图是为数据库结果创建一个缓存服务,我可以根据客户机的请求对其进行不同的分页 因此,根据(搜索)请求,我制作了一个由参数组成的键,参数的形式为两个Map和一个: public class DocMaintainer { public Manipulator creator; public Manipulator lastChange; @Override public boolean equals(Object o) { if (this =

我的意图是为数据库结果创建一个缓存服务,我可以根据客户机的请求对其进行不同的分页

因此,根据(搜索)请求,我制作了一个由参数组成的键,参数的形式为两个
Map
和一个:

public class DocMaintainer {
    public Manipulator creator;
    public Manipulator lastChange;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        DocMaintainer that = (DocMaintainer) o;
        return Objects.equals(creator, that.creator) &&
                Objects.equals(lastChange, that.lastChange);
    }

    @Override
    public int hashCode() {

        return Objects.hash(creator, lastChange);
    }
}


public class Manipulator {
    public Date fromDate;
    public Date toDate;
    public String userId;
    public String system;

    public Manipulator() {
        this.userId = "";
        this.system = "";
        this._fromJoda = new DateTime(Long.MIN_VALUE);
        this._toJoda = new DateTime(Long.MAX_VALUE - DateTimeConstants.MILLIS_PER_WEEK);
    }

    private DateTime _fromJoda;
    private DateTime _toJoda;

    public DateTime get_fromJoda() {
        _fromJoda = fromDate != null ? new DateTime(fromDate) : _fromJoda;
        return _fromJoda;
    }

    public DateTime get_toJoda() {
        _toJoda = toDate != null ? new DateTime(toDate) : _toJoda;
        try {
            _toJoda = _toJoda.plusDays(1);
        } catch (Exception e) {
            System.out.println(e);
        }

        return _toJoda;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Manipulator that = (Manipulator) o;
        return Objects.equals(fromDate, that.fromDate) &&
                Objects.equals(toDate, that.toDate) &&
                Objects.equals(userId, that.userId) &&
                Objects.equals(system, that.system);
    }

    @Override
    public int hashCode() {

        return Objects.hash(fromDate, toDate, userId, system);
    }
}
如您所见,我打算使用哈希创建一个“键”:

key对象直接用作singleton服务中的缓存键:

@Named
@Singleton
public class SearchCacheSrv {

    private Map<SearchKey, ValidMainteinersList<FindDTO>> cache = new HashMap<>();

    public ValidMainteinersList<FindDTO> getCached(SearchKey searchKey) {
        if (cache.containsKey(searchKey))
            return cache.get(searchKey);
        else
            return new ValidMainteinersList<FindDTO>();
    }

    public SearchKey makeAkey(Map<String, String[]> conjunction,
                              Map<String, String[]> disjunction,
                              DocMaintainer maintainer) {
        return new SearchKey(conjunction.hashCode(), disjunction.hashCode(), maintainer.hashCode());
    }

    public ValidMainteinersList<FindDTO> cache(SearchKey searchKey, ValidMainteinersList<FindDTO> findDTOS) {
        return cache.put(searchKey, findDTOS);
    }

    public void clearCache() {
        cache.clear();
    }
}
@Named
@独生子女
公共类SearchCacheSrv{
私有映射缓存=新的HashMap();
公共有效维护列表getCached(SearchKey SearchKey){
if(cache.containsKey(searchKey))
返回cache.get(searchKey);
其他的
返回新的ValidMaintenerList();
}
公共搜索密钥Makakey(地图连接,
地图析取,
文档维护器(文档维护器){
返回新的搜索键(conjunction.hashCode()、disconjunction.hashCode()、mainter.hashCode());
}
公共ValidMaintenerList缓存(SearchKey SearchKey,ValidMaintenerList findDTOS){
返回cache.put(searchKey,findDTOS);
}
公共void clearCache(){
cache.clear();
}
}

不幸的是,这不是我所期望的,我得到的是为相同参数生成的不同散列/键


当然问题是为什么?

这里的问题是数组的
hashCode
。这意味着,如果有两个相等的合取/析取键,但包含的数组不是相同的对象,则键的哈希代码将不同


可能最省力的解决方案是用
ArrayList
s替换数组,这些数组的
hashCode
是基于的。

我实际上看不到传递连接的意义。hashCode()。。。到您的搜索键构造函数;我从来没有这样做过,但这可能是我的错误。
尝试将实际值传递给SearchKey类,而不是hashCodes,这样hashCode方法总是返回一个一致的值。

“不幸的是,这不是我所期望的”您期望的是什么?它的行为如何?在Java应用程序的执行过程中,每当在同一对象上多次调用它时,hashCode方法必须一致地返回相同的整数,前提是不修改对象上的equals比较中使用的信息。从一个应用程序的一次执行到同一个应用程序的另一次执行,这个整数不需要保持一致。好吧,这就是发生的事情,但为什么会发生呢?某个对象的实例是否在其中扮演了某种角色?请提供一个例子,演示如何使用此代码,提供示例输入、预期输出和实际输出。这里列出了我的每个类。你要我做什么?在plunker上引导部署到tomcat的企业java后端?获得一些真实的生活是的,这样更干净,我这样做的原因是为了更明确,更容易阅读。当然,这并不是一个解决我的问题的办法,我的问题得到了公认的答案;
@Named
@Singleton
public class SearchCacheSrv {

    private Map<SearchKey, ValidMainteinersList<FindDTO>> cache = new HashMap<>();

    public ValidMainteinersList<FindDTO> getCached(SearchKey searchKey) {
        if (cache.containsKey(searchKey))
            return cache.get(searchKey);
        else
            return new ValidMainteinersList<FindDTO>();
    }

    public SearchKey makeAkey(Map<String, String[]> conjunction,
                              Map<String, String[]> disjunction,
                              DocMaintainer maintainer) {
        return new SearchKey(conjunction.hashCode(), disjunction.hashCode(), maintainer.hashCode());
    }

    public ValidMainteinersList<FindDTO> cache(SearchKey searchKey, ValidMainteinersList<FindDTO> findDTOS) {
        return cache.put(searchKey, findDTOS);
    }

    public void clearCache() {
        cache.clear();
    }
}