我希望WeakReference类覆盖hashCode并等于像这样的方法
class WeakReference<T>{
T ref;
int hashCode(){
return ref.hashCode();
}
boolean equals(Object o){
return ref.equals(o);
}
}
这样我就可以直接使用We WeakReference作为
等散列图中的关键字Person p1 = new Person("p1");
WeakReference<Person> wr = new WeakReference<Person>(p1);
map.put(wr, "some value object");
但是当我测试时,我发现hashCode和equals没有被覆盖
Person p1 = new Person("p1");
WeakReference<Person> wr = new WeakReference<Person>(p1);
WeakReference<Person> wr2 = new WeakReference<Person>(p1);
System.out.println(wr.hashCode()); // prints x
System.out.println(wr2.hashCode()); // prints y
System.out.println(wr.equals(wr2)); // prints false
在WeakReference类中没有覆盖hashCode和equals的任何特定原因?
答案 0 :(得分:4)
Map上的任何键(或Set的元素)的一个重要方面是,一旦将其添加到集合中,它必须是不可变的(或至少不会更改)。更改密钥具有未定义的行为,这种行为极不可行。
WeakReference可以随时更改,因为执行了GC,即无法控制,这使得equals / hashCode不适合使用这些的一般集合。
我试图制作MyWeakConcurrentHashMap
这样做的一个简单方法是使用WeakHashMaps数组。例如32个分区。使用hashCode()来确定要使用的WeakHashMap。这样你就可以让一个线程一次访问每个WeakHashMap(最好的情况)
由于您有更多的并发性,您可以增加分区数。
答案 1 :(得分:0)
似乎 WeakHashMap
使用 Entry
扩展 WeakReference
并覆盖 hashCode
和 equals
,
您可以查看它们的实现。
/**
* The entries in this hash table extend WeakReference, using its main ref
* field as the key.
*/
private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V> {
V value;
final int hash;
Entry<K,V> next;
/**
* Creates new entry.
*/
Entry(Object key, V value,
ReferenceQueue<Object> queue,
int hash, Entry<K,V> next) {
super(key, queue);
this.value = value;
this.hash = hash;
this.next = next;
}
@SuppressWarnings("unchecked")
public K getKey() {
return (K) WeakHashMap.unmaskNull(get());
}
public V getValue() {
return value;
}
public V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
}
public boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
K k1 = getKey();
Object k2 = e.getKey();
if (k1 == k2 || (k1 != null && k1.equals(k2))) {
V v1 = getValue();
Object v2 = e.getValue();
if (v1 == v2 || (v1 != null && v1.equals(v2)))
return true;
}
return false;
}
public int hashCode() {
K k = getKey();
V v = getValue();
return Objects.hashCode(k) ^ Objects.hashCode(v);
}
public String toString() {
return getKey() + "=" + getValue();
}
}