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

org.fujion.common.WeakMap Maven / Gradle / Ivy

There is a newer version: 3.1.0
Show newest version
/*
 * #%L
 * fujion
 * %%
 * Copyright (C) 2018 Fujion Framework
 * %%
 * 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.
 *
 * #L%
 */
package org.fujion.common;

import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.AbstractCollection;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * Implements the equivalent of a map with weakly referenced values. Note: this differs from a
 * WeakHashMap which uses weakly referenced keys.
 * 
 * @param  Class of key.
 * @param  Class of element.
 */
public class WeakMap extends WeakCollectionBaseimplements Map {
    
    private final Map> referenceMap = new HashMap<>();
    
    public WeakMap() {
        super();
    }
    
    /**
     * Copy constructor
     * 
     * @param source Instance to be copied.
     */
    public WeakMap(WeakMap source) {
        super();
        
        for (Entry entry : source.entrySet()) {
            if (entry.getValue() != null) {
                put(entry.getKey(), entry.getValue());
            }
        }
    }
    
    /**
     * Returns the size of the underlying list.
     */
    @Override
    public int size() {
        compact();
        return referenceMap.size();
    }
    
    @Override
    public boolean isEmpty() {
        compact();
        return referenceMap.isEmpty();
    }
    
    @Override
    public boolean containsKey(Object key) {
        compact();
        return referenceMap.containsKey(key);
    }
    
    @Override
    public boolean containsValue(Object value) {
        compact();
        return contains(referenceMap.values(), value);
    }
    
    @Override
    public E get(Object key) {
        return getReferent(referenceMap.get(key));
    }
    
    @Override
    public E put(K key, E value) {
        return getReferent(referenceMap.put(key, createWeakReference(value)));
    }
    
    @Override
    public void putAll(Map map) {
        for (Entry entry : map.entrySet()) {
            put(entry.getKey(), entry.getValue());
        }
    }
    
    @Override
    public Set> entrySet() {
        compact();
        
        return new AbstractSet>() {
            
            @Override
            public Iterator> iterator() {
                return new Iterator>() {
                    
                    Iterator>> iterator = referenceMap.entrySet().iterator();
                    
                    @Override
                    public boolean hasNext() {
                        return iterator.hasNext();
                    }
                    
                    @Override
                    public Entry next() {
                        final Entry> entry = iterator.next();
                        
                        return new Entry() {
                            
                            @Override
                            public K getKey() {
                                return entry.getKey();
                            }
                            
                            @Override
                            public E getValue() {
                                return getReferent(entry.getValue());
                            }
                            
                            @Override
                            public E setValue(E value) {
                                return getReferent(entry.setValue(createWeakReference(value)));
                            }
                            
                        };
                    }
                    
                    @Override
                    public void remove() {
                        throw new UnsupportedOperationException();
                    }
                };
            }
            
            @Override
            public int size() {
                return referenceMap.size();
            }
            
        };
    }
    
    @Override
    public E remove(Object key) {
        return getReferent(referenceMap.remove(key));
    }
    
    @Override
    public void clear() {
        compact();
        referenceMap.clear();
    }
    
    @Override
    public Set keySet() {
        compact();
        return referenceMap.keySet();
    }
    
    @Override
    public Collection values() {
        compact();
        
        return new AbstractCollection() {
            
            @Override
            public Iterator iterator() {
                return getIterator(referenceMap.values());
            }
            
            @Override
            public int size() {
                return referenceMap.size();
            }
            
        };
    }
    
    @Override
    protected void removeReference(Reference reference) {
        referenceMap.values().remove(reference);
    }
    
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy