Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么java类WeakReference不重写hashcode和equals_Java_Weak References - Fatal编程技术网

为什么java类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(); }

我希望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();
}
布尔等于(对象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感谢这次精彩的讨论,并阐明了这一点。