package com.revolsys.collection.map;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import com.revolsys.collection.ReferenceEntrySet;
import com.revolsys.collection.ReferenceSet;
public class WeakKeyValueMap<K, V> implements Map<K, V> {
private final Map<K, Reference<V>> map = new WeakHashMap<>();
public WeakKeyValueMap() {
}
@Override
public void clear() {
this.map.clear();
}
@Override
public boolean containsKey(final Object key) {
return this.map.containsKey(key);
}
@Override
public boolean containsValue(final Object value) {
return this.map.containsValue(value);
}
@Override
public Set<Entry<K, V>> entrySet() {
return new ReferenceEntrySet<>(this.map.entrySet());
}
public void evict(final K key) {
this.map.remove(key);
}
@Override
public V get(final Object key) {
V value = null;
final Reference<V> reference = this.map.get(key);
if (reference != null) {
value = reference.get();
}
if (value == null) {
this.map.remove(key);
}
return value;
}
@Override
public boolean isEmpty() {
return this.map.isEmpty();
}
@Override
public Set<K> keySet() {
return this.map.keySet();
}
@Override
public V put(final K key, final V value) {
V oldValue = null;
if (value == null) {
final Reference<V> oldReference = this.map.remove(key);
if (oldReference != null) {
oldValue = oldReference.get();
}
} else {
final Reference<V> oldReference = this.map.put(key, new WeakReference<>(value));
if (oldReference != null) {
oldValue = oldReference.get();
}
}
return oldValue;
}
@Override
public void putAll(final Map<? extends K, ? extends V> map) {
for (final Entry<? extends K, ? extends V> entry : map.entrySet()) {
final K key = entry.getKey();
final V value = entry.getValue();
put(key, value);
}
}
@Override
public V remove(final Object obj) {
final Reference<V> oldReference = this.map.remove(obj);
if (oldReference == null) {
return null;
} else {
return oldReference.get();
}
}
@Override
public int size() {
return this.map.size();
}
@Override
public Collection<V> values() {
return new ReferenceSet<>(this.map.values());
}
}