com.couchbase.lite.support.WeakValueHashMap Maven / Gradle / Ivy
package com.couchbase.lite.support;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
public class WeakValueHashMap extends AbstractMap {
private HashMap> references;
private ReferenceQueue referenceQueue;
public WeakValueHashMap() {
references = new HashMap>();
referenceQueue = new ReferenceQueue();
}
public WeakValueHashMap(Map extends K, ? extends V> map) {
this();
for (Map.Entry extends K, ? extends V> entry : map.entrySet() ) {
put(entry.getKey(), entry.getValue());
}
}
@Override
public V put(K key, V value) {
pruneDeadReferences();
WeakValue valueRef = new WeakValue(key, value, referenceQueue);
return getReferenceValue(references.put(key, valueRef));
};
@Override
public V get(Object key) {
pruneDeadReferences();
return getReferenceValue(references.get(key));
}
@Override
public V remove(Object key) {
V value = getReferenceValue(references.get(key));
references.remove(key);
return value;
}
@Override
public void clear() {
references.clear();
}
@Override
public boolean containsKey(Object key) {
pruneDeadReferences();
return references.containsKey(key);
}
@Override
public boolean containsValue(Object value) {
pruneDeadReferences();
for (Map.Entry> entry : references.entrySet()) {
if (value == getReferenceValue(entry.getValue())) {
return true;
}
}
return false;
}
@Override
public Set keySet() {
pruneDeadReferences();
return references.keySet();
}
@Override
public int size() {
pruneDeadReferences();
return references.size();
}
@Override
public Set> entrySet() {
pruneDeadReferences();
Set> entries = new LinkedHashSet>();
for (Map.Entry> entry : references.entrySet()) {
entries.add(new AbstractMap.SimpleEntry(entry.getKey(), getReferenceValue(entry.getValue())));
}
return entries;
}
public Collection values() {
pruneDeadReferences();
Collection values = new ArrayList();
for (WeakValue valueRef : references.values()) {
values.add(getReferenceValue(valueRef));
}
return values;
}
private V getReferenceValue(WeakValue valueRef) {
return valueRef == null ? null : valueRef.get();
}
private void pruneDeadReferences() {
WeakValue valueRef;
while ( (valueRef = (WeakValue) referenceQueue.poll()) != null ) {
references.remove(valueRef.getKey());
}
}
private class WeakValue extends WeakReference {
private final K key;
private WeakValue(K key, T value, ReferenceQueue queue) {
super(value, queue);
this.key = key;
}
private K getKey() {
return key;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy