7

是否存在 HashMap 类(或 Map 接口)的实现,它允许我使用备用哈希码和等于操作...类似于如何使用 Collections.sort 中的 Comparator 以多种方式对相同类型的集合进行排序(列表,比较器)。

如果可能的话,我想避免创建一个提供所需哈希码和等于操作的密钥包装器。


就我而言,我需要这样的情况之一:

在我的 Web 应用程序中,对于每个请求,我都会加载位置/ISP 和其他数据。在代码的不同部分(在我的服务和存储库层中),我已经“最小化”了特定于其要求的缓存。

这是一个简化的代码示例:

class GeoIpData{
    private String countryName;
    private String state;
    private String city;
    private String isp;
    @Override
    public int hashCode() {
        //countryName hashCode
        //state hashCode
        //city hashCode
        //isp hashCode
    }
    @Override
    public boolean equals(Object obj) {
        // compare countryName
        // compare state
        // compare city
        // compare isp
    }
}

 Map<GeoIpData,#Type1> fullCache = ... //This cache needs to be unique per countryName,state,city and isp
 Map<GeoIpData,#Type2> countryCache = ... //This cache needs to be unique per countryName
 Map<GeoIpData,#Type2> ispCache = ... //This cache needs to be unique per countryName,isp

为了实现这一点,上述 3 个映射需要 3 个不同的 hashcode 和 equals 方法。

fullCache:
hashCode -> GeoIpData.hashCode();
equals   -> GeoIpData.equals(Object obj);

countryCache:
hashCode -> {countryName hashCode }
equals   -> {compare countryName }

ispCache:
hashCode -> {countryName hashCode & isp hashCode }
equals   -> {compare countryName & compare isp hashCode }
4

2 回答 2

8

GNU Trove允许您为特定的 TObjectHashingStrategy 提供您自己的哈希和等于 TCustomHashMap 的函数。

于 2013-03-03T10:23:40.460 回答
1

最初的 Java API 有界equals/hashCode行为类型(类),因为那时他们没有 lambda。

为了重用现有的 API / 实现 - 制作临时密钥:

public CountryKey {
    private String country;
    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof CountryKey)) { return false; }
        CountryKey that = (CountryKey) obj;
        return this.country.equals(that.country);
    }
    @Override int hashCode() {
         return country.hashCode();
    }
}

或包装:

public CountryKey {
    private GeoIpData holder;
    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof CountryKey)) { return false; }
        CountryKey that = (CountryKey) obj;
        return this.holder.getCountry().equals(that.holder.getCountry());
    }
    @Override int hashCode() {
         return holder.getCountry().hashCode();
    }
}

并为键编写辅助构造函数:

public class GeoIpData {
     public CountryKey buildCountryKey() {
          return new CountryKey(this.country);
     }
}
于 2020-06-22T13:48:31.947 回答