Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   * http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 package com.gh.bmd.jrt.util;
 
 import java.util.Map;
 import java.util.Set;
 
Map implementation combining the features of java.util.IdentityHashMap and java.util.WeakHashMap.

Note that the map entries might change each time the object is explicitly accessed.

Created by davide-maestroni on 11/17/14.

Parameters:
<K> the key type.
<V> the value type.
 
 public class WeakIdentityHashMap<K, V> implements Map<K, V> {
 
     private final HashMap<IdentityWeakReference, V> mMap;
 
     private final ReferenceQueue<ObjectmQueue = new ReferenceQueue<Object>();
 
     private AbstractSet<Entry<K, V>> mEntrySet;
 
     private AbstractSet<K> mKeySet;

    
Constructor.
 
     public WeakIdentityHashMap() {
 
          = new HashMap<IdentityWeakReference, V>();
     }

    
Constructor.

Parameters:
map the initial content.
See also:
java.util.HashMap.java.util.HashMap.(java.util.Map)
 
     public WeakIdentityHashMap(@Nonnull final Map<? extends K, ? extends V> map) {
 
          = new HashMap<IdentityWeakReference, V>(map.size());
         putAll(map);
     }

    
Constructor.

Parameters:
initialCapacity the initial capacity.
See also:
java.util.HashMap.java.util.HashMap.(int)
 
     public WeakIdentityHashMap(final int initialCapacity) {
 
          = new HashMap<IdentityWeakReference, V>(initialCapacity);
     }

    
Constructor.

Parameters:
initialCapacity the initial capacity.
loadFactor the load factor.
See also:
java.util.HashMap.java.util.HashMap.(int,float)
 
     public WeakIdentityHashMap(final int initialCapacityfinal float loadFactor) {
 
          = new HashMap<IdentityWeakReference, V>(initialCapacityloadFactor);
     }
 
     @Override
     public int hashCode() {
 
         return .hashCode();
     }
 
     public int size() {
 
         cleanUp();
        return .size();
    }
    public boolean isEmpty() {
        cleanUp();
        return .isEmpty();
    }
    public boolean containsKey(final Object o) {
        cleanUp();
        return .containsKey(new IdentityWeakReference(o));
    }
    public boolean containsValue(final Object o) {
        cleanUp();
        return .containsValue(o);
    }
    public V get(final Object o) {
        cleanUp();
        return .get(new IdentityWeakReference(o));
    }
    public V put(final K kfinal V v) {
        cleanUp();
        return .put(new IdentityWeakReference(k), v);
    }
    public V remove(final Object o) {
        cleanUp();
        return .remove(new IdentityWeakReference(o));
    }
    public void putAll(@Nonnull final Map<? extends K, ? extends V> map) {
        cleanUp();
        final ReferenceQueue<Objectqueue = ;
        final HashMap<IdentityWeakReference, V> referenceMap = ;
        for (final Entry<? extends K, ? extends V> entry : map.entrySet()) {
            referenceMap.put(new IdentityWeakReference(entry.getKey(), queue), entry.getValue());
        }
    }
    public void clear() {
        .clear();
    }
    @Nonnull
    public Set<K> keySet() {
        if ( == null) {
             = new AbstractSet<K>() {
                @Nonnull
                @Override
                public Iterator<K> iterator() {
                    return new KeyIterator();
                }
                @Override
                public int size() {
                    return .size();
                }
            };
        }
        return ;
    }
    @Nonnull
    public Collection<V> values() {
        return .values();
    }
    @Nonnull
    public Set<Entry<K, V>> entrySet() {
        if ( == null) {
             = new AbstractSet<Entry<K, V>>() {
                @Nonnull
                @Override
                public Iterator<Entry<K, V>> iterator() {
                    return new EntryIterator();
                }
                @Override
                public int size() {
                    return .size();
                }
            };
        }
        return ;
    }
    @SuppressWarnings("unchecked")
    private void cleanUp() {
        final HashMap<IdentityWeakReference, V> map = ;
        final ReferenceQueue<Objectqueue = ;
        IdentityWeakReference reference = (IdentityWeakReferencequeue.poll();
        while (reference != null) {
            map.remove(reference);
            reference = (IdentityWeakReferencequeue.poll();
        }
    }

    
Weak reference using object identity for comparison.
    private static class IdentityWeakReference extends WeakReference<Object> {
        private final int mHashCode;

        
Constructor.

Parameters:
referent the referent instance.
queue the reference queue.
See also:
java.lang.ref.WeakReference.java.lang.ref.WeakReference.(java.lang.Object,java.lang.ref.ReferenceQueue)
        public IdentityWeakReference(final Object referent,
                final ReferenceQueue<? super Objectqueue) {
            super(referentqueue);
             = System.identityHashCode(referent);
        }

        
Constructor.

Parameters:
referent the referent instance.
See also:
java.lang.ref.WeakReference.java.lang.ref.WeakReference.(java.lang.Object)
        private IdentityWeakReference(final Object referent) {
            super(referent);
             = System.identityHashCode(referent);
        }
        @Override
        public int hashCode() {
            return ;
        }
        @Override
        public boolean equals(final Object obj) {
            if (this == obj) {
                return true;
            }
            if (!(obj instanceof IdentityWeakReference)) {
                return false;
            }
            final IdentityWeakReference that = (IdentityWeakReferenceobj;
            if ( != that.mHashCode) {
                return false;
            }
            final Object referent = get();
            return (referent != null) && (referent == that.get());
        }
    }

    
Map entry iterator.
    private class EntryIterator implements Iterator<Entry<K, V>> {
        private final Iterator<IdentityWeakReferencemIterator = .keySet().iterator();
        public boolean hasNext() {
            return .hasNext();
        }
        public Entry<K, V> next() {
            return new WeakEntry(.next());
        }
        public void remove() {
            .remove();
        }
    }

    
Map key iterator.
    private class KeyIterator implements Iterator<K> {
        private final Iterator<IdentityWeakReferencemIterator = .keySet().iterator();
        public boolean hasNext() {
            return .hasNext();
        }
        @SuppressWarnings("unchecked")
        public K next() {
            return (K) .next().get();
        }
        public void remove() {
            .remove();
        }
    }

    
Map entry implementation.
    private class WeakEntry implements Entry<K, V> {
        private final IdentityWeakReference mReference;

        
Constructor.

Parameters:
key the key reference.
        private WeakEntry(@Nonnull final IdentityWeakReference key) {
             = key;
        }
        @SuppressWarnings("unchecked")
        public K getKey() {
            return (K) .get();
        }
        public V getValue() {
            return .get();
        }
        public V setValue(final V v) {
            return .put(v);
        }
    }
    @Override
    @SuppressWarnings("EqualsBetweenInconvertibleTypes")
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof WeakIdentityHashMap)) {
            return (o instanceof Map) && o.equals(this);
        }
        final WeakIdentityHashMap<?, ?> that = (WeakIdentityHashMap<?, ?>) o;
        return .equals(that.mMap);
    }
New to GrepCode? Check out our FAQ X