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

aQute.lib.collections.DoubleKeyMap Maven / Gradle / Ivy

package aQute.lib.collections;

import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class DoubleKeyMap extends HashMap> implements Map> {
	private static final long	serialVersionUID	= 1L;
	private final Class		k1Class;
	private final Class		k2Class;
	private final Class		valueClass;

	public DoubleKeyMap() {
		k1Class = Object.class;
		k2Class = Object.class;
		valueClass = Object.class;
	}

	public DoubleKeyMap(Class k1Class, Class k2Class, Class valueClass) {
		this.k1Class = k1Class;
		this.k2Class = k2Class;
		this.valueClass = valueClass;
	}

	public DoubleKeyMap(Map> other) {
		this();
		for (java.util.Map.Entry> e : other.entrySet()) {
			putAll(e.getKey(), e.getValue());
		}
	}

	public DoubleKeyMap(DoubleKeyMap other) {
		k1Class = other.k1Class;
		k2Class = other.k2Class;
		valueClass = other.valueClass;

		for (java.util.Map.Entry> e : other.entrySet()) {
			putAll(e.getKey(), e.getValue());
		}
	}

	@SuppressWarnings("unchecked")
	public V put(K1 key1, K2 key2, V value) {
		assert k1Class.isInstance(key1);
		assert k2Class.isInstance(key2);
		assert valueClass.isInstance(value);

		Map map = get(key1);
		if (map == null) {
			map = new HashMap<>();
			if (valueClass != Object.class) {
				map = Collections.checkedMap(map, (Class) k2Class, (Class) valueClass);
			}
			put(key1, map);
		}
		return map.put(key2, value);
	}

	public V get(K1 key1, K2 key2) {
		Map map = get(key1);
		if (map == null)
			return null;

		return map.get(key2);
	}

	public boolean containsKeys(K1 key1, K2 key2) {
		Map map = get(key1);
		if (map == null)
			return false;

		return map.containsKey(key2);
	}

	public void putAll(K1 key1, Map map) {
		assert k1Class.isInstance(key1);

		for (Map.Entry e : map.entrySet()) {
			put(key1, e.getKey(), e.getValue());
		}
	}

	public boolean removeValue(K1 key1, K2 key2, V value) {
		assert k1Class.isInstance(key1);
		assert k2Class.isInstance(key2);
		assert valueClass.isInstance(value);

		Map set = get(key1);
		if (set == null) {
			return false;
		}
		boolean result = set.values()
			.remove(value);
		if (set.isEmpty())
			remove(key1);
		return result;
	}

	public V removeKey(K1 key1, K2 key2) {
		assert k1Class.isInstance(key1);
		assert k2Class.isInstance(key2);

		Map set = get(key1);
		if (set == null) {
			return null;
		}
		V result = set.remove(key2);
		if (set.isEmpty())
			remove(key1);
		return result;
	}

	public Iterator> iterate(K1 key) {
		assert k1Class.isInstance(key);
		Map set = get(key);
		if (set == null)
			return new Iterator>() {

				@Override
				public boolean hasNext() {
					return false;
				}

				@Override
				public Map.Entry next() {
					throw new UnsupportedOperationException();
				}

				@Override
				public void remove() {
					throw new UnsupportedOperationException();
				}

			};
		return set.entrySet()
			.iterator();
	}

	public Iterator all() {
		return new Iterator() {
			Iterator>>	master	= entrySet().iterator();
			Iterator>						current	= null;

			@Override
			public boolean hasNext() {
				if (current == null || !current.hasNext()) {
					if (master.hasNext()) {
						current = master.next()
							.getValue()
							.entrySet()
							.iterator();
						return current.hasNext();
					}
					return false;
				}
				return true;
			}

			@Override
			public V next() {
				return current.next()
					.getValue();
			}

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

		};
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy