为什么 java class WeakReference 不覆盖 hashcode 和 equals
why java class WeakReference does not override hashcode and equals
我期待 WeakReference class 覆盖像这样的 hashCode 和 equals 方法
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 的任何具体原因 class?
Map(或 Set 的元素)上的任何键的一个重要方面是,一旦将其添加到集合中,它就必须是不可变的(或至少不能更改)。更改密钥具有未定义的行为,这种行为极不可能起作用。
由于 GC 的执行,弱引用可以随时更改,即以您无法控制的方式更改,这使得 equals/hashCode 不适合使用这些的一般集合。
I was trying to make MyWeakConcurrentHashMap
一个简单的方法是使用一组 WeakHashMap。例如32个分区。使用 hashCode() 来确定使用哪个 WeakHashMap。这样你就可以让一个线程同时访问每个单独的 WeakHashMap(最好的情况)
随着并发性的提高,您可以增加分区数。
似乎 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();
}
}
我期待 WeakReference class 覆盖像这样的 hashCode 和 equals 方法
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 的任何具体原因 class?
Map(或 Set 的元素)上的任何键的一个重要方面是,一旦将其添加到集合中,它就必须是不可变的(或至少不能更改)。更改密钥具有未定义的行为,这种行为极不可能起作用。
由于 GC 的执行,弱引用可以随时更改,即以您无法控制的方式更改,这使得 equals/hashCode 不适合使用这些的一般集合。
I was trying to make MyWeakConcurrentHashMap
一个简单的方法是使用一组 WeakHashMap。例如32个分区。使用 hashCode() 来确定使用哪个 WeakHashMap。这样你就可以让一个线程同时访问每个单独的 WeakHashMap(最好的情况)
随着并发性的提高,您可以增加分区数。
似乎 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();
}
}