All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.holoeverywhere.util.WeaklyMap Maven / Gradle / Ivy

The newest version!

package org.holoeverywhere.util;

import java.lang.ref.WeakReference;
import java.util.AbstractCollection;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;

public class WeaklyMap extends AbstractMap {
    private static final class WeaklyEntry implements Entry {
        private final Entry> mEntry;

        public WeaklyEntry(Entry> entry) {
            mEntry = entry;
        }

        @Override
        public K getKey() {
            return mEntry.getKey();
        }

        @Override
        public V getValue() {
            final WeaklyReference ref = mEntry.getValue();
            return ref == null ? null : ref.get();
        }

        @Override
        public V setValue(V object) {
            final WeaklyReference ref = mEntry.setValue(new WeaklyReference(object));
            return ref == null ? null : ref.get();
        }
    }

    private static final class WeaklyReference extends WeakReference {
        public WeaklyReference(T r) {
            super(r);
        }

        @Override
        public boolean equals(Object o) {
            if (!(o instanceof WeaklyReference)) {
                return false;
            }
            final Object o1 = ((WeaklyReference) o).get();
            final Object o2 = get();
            return o1 != null && o2 != null && o1 == o2;
        }
    }

    private final WeakHashMap> mMap;

    public WeaklyMap() {
        mMap = new WeakHashMap>();
    }

    @Override
    public void clear() {
        mMap.clear();
    }

    @Override
    public boolean containsKey(Object key) {
        return mMap.containsKey(key);
    }

    @Override
    public boolean containsValue(Object value) {
        return mMap.containsValue(new WeaklyReference(value));
    }

    @Override
    public Set> entrySet() {
        final Set>> entrySet = mMap.entrySet();
        return new AbstractSet>() {
            @Override
            public Iterator> iterator() {
                final Iterator>> iterator = entrySet.iterator();
                return new Iterator>() {

                    @Override
                    public boolean hasNext() {
                        return iterator.hasNext();
                    }

                    @Override
                    public Entry next() {
                        return new WeaklyEntry(iterator.next());
                    }

                    @Override
                    public void remove() {
                        iterator.remove();
                    }
                };
            }

            @Override
            public int size() {
                return entrySet.size();
            }
        };
    }

    @Override
    public V get(Object key) {
        WeaklyReference ref = mMap.get(key);
        return ref == null ? null : ref.get();
    }

    @Override
    public boolean isEmpty() {
        return mMap.isEmpty();
    }

    @Override
    public Set keySet() {
        return mMap.keySet();
    }

    @Override
    public V put(K key, V value) {
        WeaklyReference ref = mMap.put(key, new WeaklyReference(value));
        return ref == null ? null : ref.get();
    }

    @Override
    public void putAll(Map map) {
        for (Entry entry : map.entrySet()) {
            mMap.put(entry.getKey(), new WeaklyReference(entry.getValue()));
        }
    }

    @Override
    public V remove(Object key) {
        WeaklyReference ref = mMap.remove(key);
        return ref == null ? null : ref.get();
    }

    @Override
    public int size() {
        return mMap.size();
    }

    @Override
    public Collection values() {
        final Collection> values = mMap.values();
        return new AbstractCollection() {
            @Override
            public Iterator iterator() {
                final Iterator> iterator = values.iterator();
                return new Iterator() {

                    @Override
                    public boolean hasNext() {
                        return iterator.hasNext();
                    }

                    @Override
                    public V next() {
                        WeaklyReference ref = iterator.next();
                        return ref == null ? null : ref.get();
                    }

                    @Override
                    public void remove() {
                        iterator.remove();
                    }
                };
            }

            @Override
            public int size() {
                return values.size();
            }
        };
    }
}