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

javolution.util.internal.map.MapView Maven / Gradle / Ivy

The newest version!
/*
 * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
 * Copyright (C) 2012 - Javolution (http://javolution.org/)
 * All rights reserved.
 * 
 * Permission to use, copy, modify, and distribute this software is
 * freely granted, provided that this notice is preserved.
 */
package javolution.util.internal.map;

import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;

import javolution.util.function.Consumer;
import javolution.util.function.Equality;
import javolution.util.function.Function;
import javolution.util.internal.collection.MappedCollectionImpl;
import javolution.util.internal.set.MappedSetImpl;
import javolution.util.internal.set.SetView;
import javolution.util.service.CollectionService;
import javolution.util.service.MapService;
import javolution.util.service.SetService;

/**
 * Map view implementation; can be used as root class for implementations 
 * if target is {@code null}.
 */
public abstract class MapView implements MapService {

    /**
     * Entry comparator. Entries are considered equals if they have the same 
     * keys regardless of their associated values.
     */
    protected class EntryComparator implements Equality>, Serializable {
        private static final long serialVersionUID = MapView.serialVersionUID;

        public EntryComparator() {
        }

        @Override
        public boolean areEqual(Entry left, Entry right) {
            return keyComparator().areEqual(left.getKey(),
                    right.getKey());
        }

        @Override
        public int compare(Entry left, Entry right) {
            return keyComparator().compare(left.getKey(),
                    right.getKey());
        }

        @Override
        public int hashCodeOf(Entry e) {
            return keyComparator().hashCodeOf(e.getKey());
        }     
    }
    
    /** Entry Set View */
    protected class EntrySet extends SetView> {
        private static final long serialVersionUID = MapView.serialVersionUID;
        public EntrySet() {
            super(null); // Actual target is the outer map. 
        }

        @Override
        public boolean add(Entry entry) {
            put(entry.getKey(), entry.getValue());
            return true;
        }

        @Override
        public Equality> comparator() {
            return new EntryComparator();
        }

        @SuppressWarnings("unchecked")
        @Override
        public boolean contains(Object obj) {
            if (obj instanceof Entry) {
                Entry e = (Entry) obj;
                return contains(e.getKey());
            }
            return false;
        }

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

        @Override
        public Iterator> iterator() {
            return MapView.this.iterator();
        }

        @Override
        public void perform(
                final Consumer>> action,
                final CollectionService> view) {
            Consumer> mapAction = new Consumer>() {
                @Override
                public void accept(MapService param) {
                    action.accept(view);
                }
            };
            MapView.this.perform(mapAction, MapView.this);
        }

        @Override
        @SuppressWarnings("unchecked")
        public boolean remove(Object obj) {
            if (obj instanceof Entry) {
                Entry e = (Entry) obj;
                if (!contains(e.getKey())) return false;
                MapView.this.remove(e.getKey());
                return true;
            }
            return false;
        }

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

        @SuppressWarnings("unchecked")
        @Override
        public CollectionService>[] split(int n) {
            MapService[] subMaps = MapView.this.split(n);
            CollectionService>[] result = new CollectionService[subMaps.length];
            for (int i = 0; i < result.length; i++) {
                result[i] = subMaps[i].entrySet();
            }
            return result;
        }

        @Override
        public void update(
                final Consumer>> action,
                final CollectionService> view) {
            Consumer> mapAction = new Consumer>() {
                @Override
                public void accept(MapService param) {
                    action.accept(view);
                }
            };
            MapView.this.update(mapAction, MapView.this);
        }
    }

    /** Key Set View */
    protected class KeySet extends MappedSetImpl, K> {
        private static final long serialVersionUID = MapView.serialVersionUID;

        public KeySet() {
            super(entrySet(), new Function, K>() {
                @Override
                public K apply(Map.Entry e) {
                    return e.getKey();
                }
            });

        }

        @Override
        public boolean add(K key) { // Supports adding new key with null value.
            if (containsKey(key)) return false;
            put(key, null);
            return true;
        }

        @Override
        public Equality comparator() {
            return keyComparator();
        }

        @SuppressWarnings("unchecked")
        @Override
        public boolean contains(Object obj) {
            return containsKey((K) obj);
        }

        @SuppressWarnings("unchecked")
        @Override
        public boolean remove(Object obj) {
            if (!containsKey((K) obj)) return false;
            MapView.this.remove((K) obj);
            return true;
        }
    }

    /** Values View */
    protected class Values extends MappedCollectionImpl, V> {
        private static final long serialVersionUID = MapView.serialVersionUID;

        public Values() {
            super(entrySet(), new Function, V>() {
                @Override
                public V apply(Map.Entry e) {
                    return e.getValue();
                }
            });
        }

        @Override
        public Equality comparator() {
            return valueComparator();
        }
    }

    private static final long serialVersionUID = 0x600L; // Version.
    private MapService target;

    /**
     * The view constructor or root class constructor if target is {@code null}.
     */
    public MapView(MapService target) {
        this.target = target;
    }

    @Override
    public void clear() {
        Iterator> it = iterator();
        while (it.hasNext()) {
            it.remove();
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public MapView clone() {
        try {
            MapView copy = (MapView) super.clone();
            if (target != null) { // Not a root class.
                copy.target = target.clone();
            }
            return copy;
        } catch (CloneNotSupportedException e) {
            throw new Error("Should not happen since target is cloneable");
        }
    }

    @Override
    public abstract boolean containsKey(Object key);

    @Override
    public boolean containsValue(Object value) {
        return values().contains(value);
    }

    @Override
    public SetService> entrySet() {
        return new EntrySet();
    }

    @Override
    public abstract V get(Object key);

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

    @Override
    public abstract Iterator> iterator();

    @Override
    public abstract Equality keyComparator();

    @Override
    public SetService keySet() {
        return new KeySet();
    }

    @Override
    public void perform(Consumer> action, MapService view) {
        if (target == null) {
            action.accept(view);
        } else {
            target.perform(action, view);
        }
    }

    @Override
    public abstract V put(K key, V value);

    @SuppressWarnings("unchecked")
    @Override
    public void putAll(Map m) {
        Iterator it = m.entrySet().iterator();
        while (it.hasNext()) {
            Entry e = (Entry) it.next();
            put(e.getKey(), e.getValue());
        }
    }

    @Override
    public V putIfAbsent(K key, V value) {
        if (!containsKey(key)) return put(key, value);
        else return get(key);
    }

    @Override
    public abstract V remove(Object key);

    @Override
    public boolean remove(Object key, Object value) {
        if (containsKey(key) && get(key).equals(value)) {
            remove(key);
            return true;
        } else return false;
    }

    @Override
    public V replace(K key, V value) {
        if (containsKey(key)) {
            return put(key, value);
        } else return null;
    }

    @Override
    public boolean replace(K key, V oldValue, V newValue) {
        if (containsKey(key) && get(key).equals(oldValue)) {
            put(key, newValue);
            return true;
        } else return false;
    }

    @Override
    public int size() {
        int count = 0;
        Iterator> it = iterator();
        while (it.hasNext()) {
            count++;
            it.next();
        }
        return count;
    }

    @SuppressWarnings("unchecked")
    @Override
    public MapService[] split(int n) {
        if (target == null) return new MapService[] { this }; // No split.
        MapService[] subTargets = target.split(n);
        MapService[] result = new MapService[subTargets.length];
        for (int i = 0; i < subTargets.length; i++) {
            MapView copy = this.clone();
            copy.target = subTargets[i];
            result[i] = copy;
        }
        return result;
    }

    @Override
    public MapService threadSafe() {
        return new SharedMapImpl(this);
    }

    @Override
    public void update(Consumer> action, MapService view) {
        if (target == null) {
            action.accept(view);
        } else {
            target.update(action, view);
        }
    }

    @Override
    public abstract Equality valueComparator();

    @Override
    public CollectionService values() {
        return new Values();
    }

    /** Returns the actual target */
    protected MapService target() {
        return target;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy