为什么java类WeakReference不重写hashcode和equals
我希望WeakReference类重写hashCode和equals方法,就像这样为什么java类WeakReference不重写hashcode和equals,java,weak-references,Java,Weak References,我希望WeakReference类重写hashCode和equals方法,就像这样 class WeakReference<T>{ T ref; int hashCode(){ return ref.hashCode(); } boolean equals(Object o){ return ref.equals(o); } } 类WeakReference{ T参考; int hashCode(){ 返回ref.hashCode(); }
class WeakReference<T>{
T ref;
int hashCode(){
return ref.hashCode();
}
boolean equals(Object o){
return ref.equals(o);
}
}
类WeakReference{
T参考;
int hashCode(){
返回ref.hashCode();
}
布尔等于(对象o){
返回参考值等于(o);
}
}
这样我就可以直接使用WeakReference作为hashmap中的键,比如
Person p1 = new Person("p1");
WeakReference<Person> wr = new WeakReference<Person>(p1);
map.put(wr, "some value object");
人员p1=新人员(“p1”);
WeakReference wr=新的WeakReference(p1);
map.put(wr,一些有价值的对象);
但是当我测试时,我发现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
人员p1=新人员(“p1”);
WeakReference wr=新的WeakReference(p1);
WeakReference wr2=新的WeakReference(p1);
System.out.println(wr.hashCode());//打印x
System.out.println(wr2.hashCode());//印刷品
System.out.println(wr.equals(wr2));//打印错误
hashCode和equals在WeakReference类中未被重写的任何具体原因?映射(或集合元素)上任何键的一个重要方面是,一旦添加到集合中,它必须是不可变的(或至少不更改)。更改密钥具有未定义的行为,这极不可能起作用 由于正在执行GC,WeakReference可以随时更改,即您无法控制的方式,这使得equals/hashCode不适用于使用它们的常规集合 我在试着做我的弱电流图 实现这一点的一个简单方法是拥有一组WeakHashMaps。e、 g.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
*字段作为键。
*/
私有静态类条目扩展WeakReference实现Map.Entry{
V值;
最终整数散列;
进入下一步;
/**
*创建新条目。
*/
输入(对象键、V值、,
引用队列,
int散列,下一个条目){
超级(键,队列);
这个值=值;
this.hash=hash;
this.next=next;
}
@抑制警告(“未选中”)
公共K getKey(){
返回(K)WeakHashMap.unmaskNull(get());
}
public V getValue(){
返回值;
}
公共V设置值(V新值){
V oldValue=值;
值=新值;
返回旧值;
}
公共布尔等于(对象o){
如果(!(映射项的实例))
返回false;
Map.Entry e=(Map.Entry)o;
kk1=getKey();
对象k2=e.getKey();
如果(k1==k2 | |(k1!=null&&k1.equals(k2))){
V v1=getValue();
对象v2=e.getValue();
如果(v1==v2 | |(v1!=null&&v1.equals(v2)))
返回true;
}
返回false;
}
公共int hashCode(){
K=getKey();
V=getValue();
返回Objects.hashCode(k)^Objects.hashCode(v);
}
公共字符串toString(){
返回getKey()+“=”+getValue();
}
}
因为没有必要,因为这将满足您的需要。如果WeakReference
已覆盖equals
和hashCode
将它们用作HashMap
键是一个非常糟糕的主意。这是因为WeakReference
的hashCode
几乎肯定会在取出所持有的对象时发生变化。您不应该在放入HashMap
键后使其发生更改,因为这样就不可能再找到它了。那么…每个收集的键都等于任何其他收集的键?这真是个坏主意……没问题。弱引用可以在其构造函数中计算哈希代码,并将其缓存,因此它永远不会更改。@MikeNakis它如何缓存相等的信息?实际上,我正试图通过在弱引用中包装ConcurrentHashMap和包装/取消包装映射键来制作MyWeakConcurrentHashMap。消费者不必意识到这一点。如果weakrefeerence按照我的期望实现了hashCode和equals,它会很好地工作。@Mangose虽然这是不可能的,因为weakrefeerence可以随时更改,所以您需要以不同的方式处理这样一个键。@PeterLawrey和mike感谢这次精彩的讨论,并阐明了这一点。