我有一个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
发生了一些碰撞,但我知道这不应该是一个问题。有什么想法吗?
答案 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);
}