📄 weakhashtable.java
字号:
Referenced keyRef = new Referenced(key, queue); return super.put(keyRef, value); } /** *@see Hashtable */ public void putAll(Map t) { if (t != null) { Set entrySet = t.entrySet(); for (Iterator it=entrySet.iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); put(entry.getKey(), entry.getValue()); } } } /** *@see Hashtable */ public Collection values() { purge(); return super.values(); } /** *@see Hashtable */ public Object remove(Object key) { // for performance reasons, only purge every // MAX_CHANGES_BEFORE_PURGE times if (changeCount++ > MAX_CHANGES_BEFORE_PURGE) { purge(); changeCount = 0; } // do a partial purge more often else if ((changeCount % PARTIAL_PURGE_COUNT) == 0) { purgeOne(); } return super.remove(new Referenced(key)); } /** *@see Hashtable */ public boolean isEmpty() { purge(); return super.isEmpty(); } /** *@see Hashtable */ public int size() { purge(); return super.size(); } /** *@see Hashtable */ public String toString() { purge(); return super.toString(); } /** * @see Hashtable */ protected void rehash() { // purge here to save the effort of rehashing dead entries purge(); super.rehash(); } /** * Purges all entries whose wrapped keys * have been garbage collected. */ private void purge() { synchronized (queue) { WeakKey key; while ((key = (WeakKey) queue.poll()) != null) { super.remove(key.getReferenced()); } } } /** * Purges one entry whose wrapped key * has been garbage collected. */ private void purgeOne() { synchronized (queue) { WeakKey key = (WeakKey) queue.poll(); if (key != null) { super.remove(key.getReferenced()); } } } /** Entry implementation */ private final static class Entry implements Map.Entry { private final Object key; private final Object value; private Entry(Object key, Object value) { this.key = key; this.value = value; } public boolean equals(Object o) { boolean result = false; if (o != null && o instanceof Map.Entry) { Map.Entry entry = (Map.Entry) o; result = (getKey()==null ? entry.getKey() == null : getKey().equals(entry.getKey())) && (getValue()==null ? entry.getValue() == null : getValue().equals(entry.getValue())); } return result; } public int hashCode() { return (getKey()==null ? 0 : getKey().hashCode()) ^ (getValue()==null ? 0 : getValue().hashCode()); } public Object setValue(Object value) { throw new UnsupportedOperationException("Entry.setValue is not supported."); } public Object getValue() { return value; } public Object getKey() { return key; } } /** Wrapper giving correct symantics for equals and hashcode */ private final static class Referenced { private final WeakReference reference; private final int hashCode; /** * * @throws NullPointerException if referant is <code>null</code> */ private Referenced(Object referant) { reference = new WeakReference(referant); // Calc a permanent hashCode so calls to Hashtable.remove() // work if the WeakReference has been cleared hashCode = referant.hashCode(); } /** * * @throws NullPointerException if key is <code>null</code> */ private Referenced(Object key, ReferenceQueue queue) { reference = new WeakKey(key, queue, this); // Calc a permanent hashCode so calls to Hashtable.remove() // work if the WeakReference has been cleared hashCode = key.hashCode(); } public int hashCode() { return hashCode; } private Object getValue() { return reference.get(); } public boolean equals(Object o) { boolean result = false; if (o instanceof Referenced) { Referenced otherKey = (Referenced) o; Object thisKeyValue = getValue(); Object otherKeyValue = otherKey.getValue(); if (thisKeyValue == null) { result = (otherKeyValue == null); // Since our hashcode was calculated from the original // non-null referant, the above check breaks the // hashcode/equals contract, as two cleared Referenced // objects could test equal but have different hashcodes. // We can reduce (not eliminate) the chance of this // happening by comparing hashcodes. if (result == true) { result = (this.hashCode() == otherKey.hashCode()); } // In any case, as our c'tor does not allow null referants // and Hashtable does not do equality checks between // existing keys, normal hashtable operations should never // result in an equals comparison between null referants } else { result = thisKeyValue.equals(otherKeyValue); } } return result; } } /** * WeakReference subclass that holds a hard reference to an * associated <code>value</code> and also makes accessible * the Referenced object holding it. */ private final static class WeakKey extends WeakReference { private final Referenced referenced; private WeakKey(Object key, ReferenceQueue queue, Referenced referenced) { super(key, queue); this.referenced = referenced; } private Referenced getReferenced() { return referenced; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -