带有ArrayLists值的HashMap在Get()调用时返回Null

时间:2013-12-11 16:28:14

标签: java arraylist

我有一个HashMap,它将我创建的对象存储为关键字,并映射到类似对象的ArrayList

但是,我正在调用get方法,并且使用jGrasp的调试器,我可以清楚地看到我在get()中使用的密钥存在,并且确实映射到array但是我能得到的唯一值是null值。

这是我获得null值的地方。

public List<Entry> query(Record query) {
     List<Entry> candList;
     Entry key = new Entry(makeKey(query));

     candList = map.get(key);

     return candList;
}

这是我从主商店填充HashMap的地方。

for(int i = 0; i < main.size(); i++) {
    if(main.get(i).isActive()) {
        values.clear();
        tmp = new Entry(main.get(i).record());
        key = new Entry(Record.make(tmp.entity(),tmp.relation(),wild));

        if(!map.containsKey(key)) {
            for(int v = 0; v < main.size(); v++) {
                value = main.get(v);

                if(key.entity().equals(value.entity()) && key.relation().equals(value.relation())) {
                    values.add(value);
                 }                        
            }

            map.put(key,new ArrayList(values));
        }
    }
}

Entry是一个包装类,默认使用其内部对象的equals()方法。

public boolean equals(Object o){
    if(o == null){ 
        return false; 
    }
    else if(o instanceof Record){
        Record r = (Record) o;
        return this.entity.equals(r.entity) && this.relation.equals(r.relation) && this.property.equals(r.property);
    }

    else return false;
}

我也在这里为对象编写了一个哈希码。

int h = 0;
public int hashCode() {

    int hash = h;

    if(h != 0) 
    return hash;

    String len = entity.concat(relation.concat(property));
    for(int i = 0; i < len.length(); i++)
        hash = hash * 31 +(int)len.charAt(i);

    return hash;
}

稍微澄清一下,Entry对象包含Record类型的对象,其中包含三个不可变的String,因此hashCode等式来自。{/ p>

为了进一步澄清,有人要求查看整个Entry课程。

private static class Entry {
    private static boolean active;
    private Record rec;

    public Entry(Record r){
      this.rec = r;
      this.active = true;
    }    

    public String entity() {
      return rec.entity;
    }

    public String relation() {
      return rec.relation;
    }

    public String property() {
      return rec.property;
    }

    public Record record(){
      return this.rec;
    }

    public boolean isActive(){
    return this.active;
    }

    public void deactivate(){
    this.active = false;
    }

    public void activate(){
    this.active = true;
    }

    public boolean equals(Entry e) {
      return this.rec.equals(e.record());
    }

    public int hashCode() {
      return this.rec.hashCode();
    }

    public String toString() {
      return rec.toString();
    }
} 

我的HashMap发生了一些碰撞,但我知道这不应该是一个问题。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

    public boolean equals(Object o){
    if(o == null){ 
        return false; 
    }
    else if(o instanceof Record){
        Record r = (Record) o;
        return this.entity.equals(r.entity) && this.relation.equals(r.relation) && this.property.equals(r.property);
    }

    else return false;
}

你的条目等于方法可能有一些问题,关系的定义是什么? 该关系必须覆盖equals()和hashCode()

将所有代码放在这里很棒,主要的定义是什么? 并且在你的代码中有很多地方包含null指针bug

答案 1 :(得分:0)

将 int 设置为 0 (int h = 0) 时,您的哈希码函数可能会出现问题……可以在 Josh Bloch 的 Effectiv Java 书籍(第 8 项)中找到一个很好的解释。

这是一个例子:

@覆盖 public int hashCode() {

int result = 17;

// this line should change depending on your fields
// let say you have a string property that is not null
result = 31 * result + property.hashCode();

return result;

}

...你也可以使用 Guava 之类的库

@覆盖 public int hashCode() {

return Objects.hashCode(this.property1, this.property2);

}