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

com.firefly.utils.collection.MultiMap Maven / Gradle / Ivy

There is a newer version: 5.0.2
Show newest version
package com.firefly.utils.collection;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * A multi valued Map.
 * 
 * @param 
 *            the entry type for multimap values
 */
public class MultiMap extends HashMap> {
	private static final long serialVersionUID = -1127515104096783129L;

	public MultiMap() {
		super();
	}

	public MultiMap(Map> map) {
		super(map);
	}

	public MultiMap(MultiMap map) {
		super(map);
	}

	/**
	 * Get multiple values. Single valued entries are converted to singleton
	 * lists.
	 * 
	 * @param name
	 *            The entry key.
	 * @return Unmodifieable List of values.
	 */
	public List getValues(String name) {
		List vals = super.get(name);
		if ((vals == null) || vals.isEmpty()) {
			return null;
		}
		return vals;
	}

	/**
	 * Get a value from a multiple value. If the value is not a multivalue, then
	 * index 0 retrieves the value or null.
	 * 
	 * @param name
	 *            The entry key.
	 * @param i
	 *            Index of element to get.
	 * @return Unmodifieable List of values.
	 */
	public V getValue(String name, int i) {
		List vals = getValues(name);
		if (vals == null) {
			return null;
		}
		if (i == 0 && vals.isEmpty()) {
			return null;
		}
		return vals.get(i);
	}

	/**
	 * Get value as String. Single valued items are converted to a String with
	 * the toString() Object method. Multi valued entries are converted to a
	 * comma separated List. No quoting of commas within values is performed.
	 * 
	 * @param name
	 *            The entry key.
	 * @return String value.
	 */
	public String getString(String name) {
		List vals = get(name);
		if ((vals == null) || (vals.isEmpty())) {
			return null;
		}

		if (vals.size() == 1) {
			// simple form.
			return vals.get(0).toString();
		}

		// delimited form
		StringBuilder values = new StringBuilder(128);
		for (V e : vals) {
			if (e != null) {
				if (values.length() > 0)
					values.append(',');
				values.append(e.toString());
			}
		}
		return values.toString();
	}

	/**
	 * Put multi valued entry.
	 * 
	 * @param name
	 *            The entry key.
	 * @param value
	 *            The simple value
	 * @return The previous value or null.
	 */
	public List put(String name, V value) {
		if (value == null) {
			return super.put(name, null);
		}
		List vals = new ArrayList<>();
		vals.add(value);
		return put(name, vals);
	}

	/**
	 * Shorthand version of putAll
	 * 
	 * @param input
	 *            the input map
	 */
	public void putAllValues(Map input) {
		for (Map.Entry entry : input.entrySet()) {
			put(entry.getKey(), entry.getValue());
		}
	}

	/**
	 * Put multi valued entry.
	 * 
	 * @param name
	 *            The entry key.
	 * @param values
	 *            The List of multiple values.
	 * @return The previous value or null.
	 */
	public List putValues(String name, List values) {
		return super.put(name, values);
	}

	/**
	 * Put multi valued entry.
	 * 
	 * @param name
	 *            The entry key.
	 * @param values
	 *            The array of multiple values.
	 * @return The previous value or null.
	 */
	@SafeVarargs
	public final List putValues(String name, V... values) {
		List list = new ArrayList<>();
		list.addAll(Arrays.asList(values));
		return super.put(name, list);
	}

	/**
	 * Add value to multi valued entry. If the entry is single valued, it is
	 * converted to the first value of a multi valued entry.
	 * 
	 * @param name
	 *            The entry key.
	 * @param value
	 *            The entry value.
	 */
	public void add(String name, V value) {
		List lo = get(name);
		if (lo == null) {
			lo = new ArrayList<>();
		}
		lo.add(value);
		super.put(name, lo);
	}

	/**
	 * Add values to multi valued entry. If the entry is single valued, it is
	 * converted to the first value of a multi valued entry.
	 * 
	 * @param name
	 *            The entry key.
	 * @param values
	 *            The List of multiple values.
	 */
	public void addValues(String name, List values) {
		List lo = get(name);
		if (lo == null) {
			lo = new ArrayList<>();
		}
		lo.addAll(values);
		put(name, lo);
	}

	/**
	 * Add values to multi valued entry. If the entry is single valued, it is
	 * converted to the first value of a multi valued entry.
	 * 
	 * @param name
	 *            The entry key.
	 * @param values
	 *            The String array of multiple values.
	 */
	public void addValues(String name, V[] values) {
		List lo = get(name);
		if (lo == null) {
			lo = new ArrayList<>();
		}
		lo.addAll(Arrays.asList(values));
		put(name, lo);
	}

	/**
	 * Merge values.
	 * 
	 * @param map
	 *            the map to overlay on top of this one, merging together values
	 *            if needed.
	 * @return true if an existing key was merged with potentially new values,
	 *         false if either no change was made, or there were only new keys.
	 */
	public boolean addAllValues(MultiMap map) {
		boolean merged = false;

		if ((map == null) || (map.isEmpty())) {
			// done
			return merged;
		}

		for (Map.Entry> entry : map.entrySet()) {
			String name = entry.getKey();
			List values = entry.getValue();

			if (this.containsKey(name)) {
				merged = true;
			}

			this.addValues(name, values);
		}

		return merged;
	}

	/**
	 * Remove value.
	 * 
	 * @param name
	 *            The entry key.
	 * @param value
	 *            The entry value.
	 * @return true if it was removed.
	 */
	public boolean removeValue(String name, V value) {
		List lo = get(name);
		if ((lo == null) || (lo.isEmpty())) {
			return false;
		}
		boolean ret = lo.remove(value);
		if (lo.isEmpty()) {
			remove(name);
		} else {
			put(name, lo);
		}
		return ret;
	}

	/**
	 * Test for a specific single value in the map.
	 * 

* NOTE: This is a SLOW operation, and is actively discouraged. * * @param value * the value to search for * @return true if contains simple value */ public boolean containsSimpleValue(V value) { for (List vals : values()) { if ((vals.size() == 1) && vals.contains(value)) { return true; } } return false; } @Override public String toString() { Iterator>> iter = entrySet().iterator(); StringBuilder sb = new StringBuilder(); sb.append('{'); boolean delim = false; while (iter.hasNext()) { Map.Entry> e = iter.next(); if (delim) { sb.append(", "); } String key = e.getKey(); List vals = e.getValue(); sb.append(key); sb.append('='); if (vals.size() == 1) { sb.append(vals.get(0)); } else { sb.append(vals); } delim = true; } sb.append('}'); return sb.toString(); } /** * @return Map of String arrays */ public Map toStringArrayMap() { HashMap map = new HashMap(size() * 3 / 2) { private static final long serialVersionUID = -6129887569971781626L; @Override public String toString() { StringBuilder b = new StringBuilder(); b.append('{'); for (String k : super.keySet()) { if (b.length() > 1) b.append(','); b.append(k); b.append('='); b.append(Arrays.asList(super.get(k))); } b.append('}'); return b.toString(); } }; for (Map.Entry> entry : entrySet()) { String[] a = null; if (entry.getValue() != null) { a = new String[entry.getValue().size()]; a = entry.getValue().toArray(a); } map.put(entry.getKey(), a); } return map; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy