所以......一切都在代码中:
// get vector...
SignVector v = ...;
//print to console: [1058, 5, 820 in flat]
System.out.println(v);
//size: 1
System.out.println("size: " + signs.size());
//check all elements...
for (Entry<SignVector, FakeSign> entry : signs.entrySet())
{
// get key
SignVector key = entry.getKey();
//print to console: [1058, 5, 820 in flat] (YaY! it's that key! like v)
System.out.println(key);
if (key.equals(v))
{
// print: "YaY: "
System.out.println("YaY: [1058, 5, 820 in flat]"+key);
}
}
//So second test... just get it from map: null
System.out.println(signs.get(v));
为什么返回null?
在JavaDocs中写道:map.get使用key.equals(k)
为什么我的代码返回好的对象,但map.get
返回null?
地图:
private final Map<SignVector, FakeSign> signs = new HashMap<>()
@home用户的等号方法形式为SignVector
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SignVector other = (SignVector) obj;
// w can't be null so I skip that
System.out.print(w.getName() + ", " + other.w.getName() + ", " + (w.getName().equals(other.w.getName()))); // this same
if (!w.getName().equals(other.w.getName()))
return false;
if (x != other.x)
return false;
if (y != other.y)
return false;
if (z != other.z)
return false;
return true;
}
但是这种方法效果很好,总是返回我想要的,x
,y
,z
是int
,w
是自定义对象。< / p>
答案 0 :(得分:4)
javadoc有点误导,但它依赖的事实是,如果你实现equals,你还应该实现hashcode以保持一致。正如文件所述:
集合框架接口中的许多方法都是用术语定义的 等于方法。例如,规范 containsKey(Object key)方法说:“当且仅当这个时返回true map包含键k的映射,使得(key == null?k == null: key.equals(k))。“
本说明书不应解释为暗示 使用非null参数键调用Map.containsKey将导致 key.equals(k)将被调用任何密钥k。
实施是免费的 实现优化,从而避免等于调用 例如,首先比较两个密钥的哈希码。 (该 Object.hashCode()规范保证两个对象具有 不等的哈希码不能相等。)
更一般地说,实现 可以免费使用各种Collections Framework接口 底层Object方法的指定行为的优点 实施者认为合适的地方。
让我们看一下get
HashMap
的基础实现。
314 public V get(Object key) {
315 if (key == null)
316 return getForNullKey();
317 int hash = hash(key.hashCode());
318 for (Entry<K,V> e = table[indexFor(hash, table.length)];
319 e != null;
320 e = e.next) {
321 Object k;
322 if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
323 return e.value;
324 }
325 return null;
326 }
您看到它使用对象的哈希码来查找表中的可能条目,然后它使用equals来确定它必须返回的值。由于条目可能为null
,因此跳过for循环,get
返回null
。
覆盖hashCode
课程中的SignVector
以与equals
保持一致,一切正常。
答案 1 :(得分:1)
来自javadocs:
如果此映射允许空值,则返回值null不一定表示映射不包含该键的映射;它也可能是地图显式地将键映射为null。 containsKey操作可用于区分这两种情况。
除非您与我们分享您如何构建地图,否则我们无法帮助您(如果是这种情况)。您共享的代码应该正常工作。
http://docs.oracle.com/javase/7/docs/api/java/util/Map.html#get%28java.lang.Object%29