gpt4 book ai didi

Java HashMap 没有找到键,但它应该

转载 作者:搜寻专家 更新时间:2023-10-31 19:30:27 24 4
gpt4 key购买 nike

我的应用程序出现了一个奇怪的问题,我将快速解释全局架构,然后深入解释我的问题。

我使用服务来填充 HashMap<DomainObject,Boolean>来 self 的数据库(JPA 驱动),它又通过 EJB 远程方法调用(使用 Apache Wicket)返回到我的 View 。在这部分,我添加了一个新的 DomainObject到返回的 map ,以便存储来 self 的最终用户的任何新值。

当用户点击其浏览器中的“添加”按钮时出现问题,我尝试在我的 map 中检索新创建的项目,但失败了。通过使用调试器,我面临以下问题。

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

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

map.containsKey(do);返回 false

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

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

如果有帮助,请将断点附加到我的 DomainObject.equals()DomainObject.hashcode()方法我发现 map.get()只打电话 hashcode()而不是 equals() .

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

我希望这里有人能给我指点,谢谢。

Environment used :

  • Sun Java 1.6.0_26 x64 under OS X 10.7.1
  • OpenJDK 1.6.0_18 x64 under Debian 6.0.2 (2.6.32)
  • Apache Wicket 1.4.17
  • Oracle Glassfish 3.1.1
  • JBoss Hibernate 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) 重新创建 map 能够找到元素,我怀疑 DomainObject 的 hashCode() 在将其添加到 map 。

例如,如果您的 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。因为 map 中的 do 对象位于 "ABC".hashCode() 的桶下; "DEF".hashCode() 桶中没有任何内容。

一旦添加到 map 中, map 中对象的哈希码不应更改。确保它的最佳方法是 hashCode 所依赖的字段必须是不可变的

关于Java HashMap 没有找到键,但它应该,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7565341/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com