当前位置: 首页 > 面试题库 >

Java HashMap找不到密钥,但是应该

宰父涵忍
2023-03-14
问题内容

我的应用程序中发生一个奇怪的问题,我将快速解释全局体系结构,然后再深入探讨我的问题。

我使用一种服务来填充HashMap<DomainObject,Boolean>来自我的数据库(由JPA驱动)的数据,然后通过EJB远程方法调用(使用Apache
Wicket)将其返回到我的视图。在这一部分中,我DomainObject向返回的地图添加了一个新值,以便存储最终用户的任何新值。

当用户在其浏览器中单击“添加”按钮时,会出现问题,我尝试在地图中检索新创建的项目,但失败。通过与调试器一起玩,我面临以下问题。

假设HashMap<DomainObject, Boolean> mapDomainObject do是两个有趣的变量,我在调试器中得到以下结果

map.keySet();给我一个对应的对象do(即使@whatever simili-
reference相同),hashcode()在两个对象上返回相似的值,并且equals()在两个返回之间true

map.containsKey(do); 退货 false

map.get(do); 返回null,很奇怪,因为我的钥匙似乎在map

假设我新创建的项目是枚举的第一个键keySet(),我执行以下操作: map.get(new ArrayList(map.keySet()).get(0)),并且它返回null。

如果有帮助,可以通过将断点附加到我的DomainObject.equals()DomainObject.hashcode()方法上来,我发现那map.get()只是在调用hashcode()而不是equals()

我发现的唯一解决方法是在现有地图上重新创建一个新地图new HashMap(map),在这个新地图中,我完全可以通过其键查找对象。

我希望这里有人可以给我一个指示,谢谢。

使用环境:

  • OS X 10.7.1下的Sun Java 1.6.0_26 x64
  • Debian 6.0.2(2.6.32)下的Openhtml" target="_blank">JDK 1.6.0_18 x64
  • Apache Wicket 1.4.17
  • Oracle Glassfish 3.1.1
  • JBoss休眠3.6.5

DomainObject 代码:

public class AssetComponentDetailTemplate extends BaseEntite<Long> {
public enum DataType {
    TXT,
    DATE,
    INT,
    JOIN,
    LIST,
    COULEURS,
    REFERENCE
}

public enum Tab {
    IDENTITE,
    LOCALISATION,
    CYCLE_DE_VIE,
    FINANCE,
    RESEAU,
    DETAIL
}

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
@Enumerated(EnumType.STRING)
private DataType dataType;
private Integer classNameId;
private Long orderId;
private Long nextAssetComponentDetailTemplateId;
private String unit;
@Enumerated(EnumType.STRING)
private Tab tab;

@Column(nullable = false)
private Long uniqueOrganizationId;

@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "idAssetComponentDetailTemplate", insertable = false, updatable = false)
private List<AssetComponentDetailJoin> assetComponentDetailJoins;

private Boolean mandatory = false;

public AssetComponentDetailTemplate() {
}

public Long getId() {
    return id;
}

public void setId(final Long id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(final String name) {
    this.name = name;
}

public DataType getDataType() {
    return dataType;
}

public void setDataType(final DataType dataType) {
    this.dataType = dataType;
}

public Integer getClassNameId() {
    return classNameId;
}

public void setClassNameId(final Integer classNameId) {
    this.classNameId = classNameId;
}

public Long getUniqueOrganizationId() {
    return uniqueOrganizationId;
}

public void setUniqueOrganizationId(final Long uniqueOrganizationId) {
    this.uniqueOrganizationId = uniqueOrganizationId;
}

public Long getNextAssetComponentDetailTemplateId() {
    return nextAssetComponentDetailTemplateId;
}

public void setNextAssetComponentDetailTemplateId(final Long nextAssetComponentDetailTemplateId) {
    this.nextAssetComponentDetailTemplateId = nextAssetComponentDetailTemplateId;
}

public String getUnit() {
    return unit;
}

public void setUnit(final String unit) {
    this.unit = unit;
}

public Tab getTab() {
    return tab;
}

public void setTab(final Tab tab) {
    this.tab = tab;
}

public Long getOrder() {
    return orderId;
}

public void setOrder(final Long order) {
    this.orderId = order;
}

public Boolean isMandatory() {
    return mandatory;
}

@Override
public String toString() {
    return name;
}

@Override
public boolean equals(final Object o) {
    if (this == o) {
        return true;
    }
    if (o == null || getClass() != o.getClass()) {
        return false;
    }

    final AssetComponentDetailTemplate that = (AssetComponentDetailTemplate) o;

    if (classNameId != null ? !classNameId.equals(that.classNameId) : that.classNameId != null) {
        return false;
    }
    if (dataType != that.dataType) {
        return false;
    }
    if (id != null ? !id.equals(that.id) : that.id != null) {
        return false;
    }
    if (name != null ? !name.equals(that.name) : that.name != null) {
        return false;
    }
    if (nextAssetComponentDetailTemplateId != null ?
        !nextAssetComponentDetailTemplateId.equals(that.nextAssetComponentDetailTemplateId) :
        that.nextAssetComponentDetailTemplateId != null) {
        return false;
    }
    if (orderId != null ? !orderId.equals(that.orderId) : that.orderId != null) {
        return false;
    }
    if (tab != that.tab) {
        return false;
    }
    if (uniqueOrganizationId != null ? !uniqueOrganizationId.equals(that.uniqueOrganizationId) :
        that.uniqueOrganizationId != null) {
        return false;
    }
    if (unit != null ? !unit.equals(that.unit) : that.unit != null) {
        return false;
    }

    return true;
}

@Override
public int hashCode() {
    int result = id != null ? id.hashCode() : 0;
    result = 31 * result + (name != null ? name.hashCode() : 0);
    result = 31 * result + (dataType != null ? dataType.hashCode() : 0);
    result = 31 * result + (classNameId != null ? classNameId.hashCode() : 0);
    result = 31 * result + (orderId != null ? orderId.hashCode() : 0);
    result = 31 * result +
             (nextAssetComponentDetailTemplateId != null ? nextAssetComponentDetailTemplateId.hashCode() : 0);
    result = 31 * result + (unit != null ? unit.hashCode() : 0);
    result = 31 * result + (tab != null ? tab.hashCode() : 0);
    result = 31 * result + (uniqueOrganizationId != null ? uniqueOrganizationId.hashCode() : 0);
    return result;
}

问题答案:

[这基本上是对Jesper的回答,但细节可能会对您有所帮助]

由于使用new HashMap(map)可以重新创建地图,因此我怀疑hashCode()DomainObject 的元素将其添加到地图后已更改。

例如,如果您的DomainObject看起来如下

class DomainObject {
    public String name;
    long hashCode() { return name.hashCode(); }
    boolean equals(Object other) { /* compare name in the two */'
}

然后

   Map<DomainObject, Boolean> m = new HashMap<DomainObject, Boolean>();
   DomainObject do = new DomainObject(); 
   do.name = "ABC";
   m.put(do, true); // do goes in the map with hashCode of ABC
   do.name = "DEF";
   m.get(do);

上面的最后一条语句将返回null。因为do您在地图内的对象位于的范围之内"ABC".hashCode()"DEF".hashCode()桶里什么也没有。

映射中的对象的hashCode一旦添加到映射中就不应更改。 确保它的最佳方法是hashCode依赖的字段必须是不可变的



 类似资料:
  • 在TransitionKey类中:

  • 我正在尝试对现有API启用Azure密钥库证书。我们已经在Azure Key Vault帐户中拥有秘密和Azure Key Vault证书。下面是配置证书的代码: 在我的本地计算机上,我正确地导入了证书,其中包括下载pfx格式。

  • 杰米特。我在系统中设置了jks的路径和密码。财产。我执行一个HTTP请求,在日志中看到一个错误: 和 日志:

  • 别名s1as被上述命令中使用的别名所取代,即server-alias(在下,上的SSL选项卡)。 jks和cacerts.jks存储在下。 下的JVM选项,上的JVM选项选项卡,以下选项 GlassFish服务器不喜欢什么? 它只在使用别名重新生成这些文件keystore.jks和cacerts.jks时工作,但当使用不同的别名(证书昵称)时,它会失败,出现给定的异常。GlassFish似乎将这个

  • 我们的android项目由移动和wear应用组成(wear应用正在开发中),我们正在尝试发布移动应用。当我们尝试生成签名的apk时,会得到以下消息: 当它读它说失败的任务:磨损:包装eRelease,实际上我们只是选择移动,而选择签署APK。 有人能指出我的错误吗?提前道谢。

  • 问题内容: 以jenkins用户身份登录时,我在〜/ .ssh / id_rsa.pub中有一个ssh密钥。 我已将其正确导入到bitbucket中,并且已经接受了密钥。 当我尝试进行git clone(正确的URL)时,我仍然得到…。 有人知道发生这种情况的原因吗?根据我读过的文档,〜/ .ssh是jenkins用户的正确目录,此文件存在。 编辑:我的jenkins用户在〜/ .ssh中没有kn