/*license*\
XBN-Java: Copyright (C) 2014, Jeff Epstein (aliteralmind __DASH__ github __AT__ yahoo __DOT__ com)
This software is dual-licensed under the:
- Lesser General Public License (LGPL) version 3.0 or, at your option, any later version;
- Apache Software License (ASL) version 2.0.
Either license may be applied at your discretion. More information may be found at
- http://en.wikipedia.org/wiki/Multi-licensing.
The text of both licenses is available in the root directory of this project, under the names "LICENSE_lgpl-3.0.txt" and "LICENSE_asl-2.0.txt". The latest copies may be downloaded at:
- LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
- ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
\*license*/
package com.github.xbn.list;
import com.github.xbn.analyze.validate.ValueFilter;
import com.github.xbn.lang.Null;
import com.github.xbn.lang.BadDuplicateException;
import com.github.xbn.lang.CrashIfObject;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import static com.github.xbn.lang.XbnConstants.*;
/**
<p>Make the list values in a map immutable and/or sorted, and pretty-printing.</p>
<h4>Iterating through a map via its entry-set</h4>
<blockquote><pre>for (Map.Entry<KeyType,ValueType> entry : map.entrySet()) {
KeyType k = entry.getKey();
ValueType v = entry.getValue();
...
}</pre></blockquote>
<p><i>From <code><a href="http://stackoverflow.com/questions/46898/how-do-i-iterate-over-each-entry-in-a-map/46908#46908">http://stackoverflow.com/questions/46898/how-do-i-iterate-over-each-entry-in-a-map/46908#46908</a></code> (downloaded 5/28/2014)</i></p>
* @author Copyright (C) 2014, Jeff Epstein, dual-licensed under the LGPL (version 3.0 or later) or the ASL (version 2.0). See source code for details. <code><a href="http://xbnjava.aliteralmind.com">http://xbnjava.aliteralmind.com</a></code>, <code><a href="https://github.com/aliteralmind/xbnjava">https://github.com/aliteralmind/xbnjava</a></code>
**/
public class MapUtil {
public static final <K,V> String toString(Map<K,V> map, ValueFilter<Map.Entry<K,V>> entryFilter_ifNonNull) {
return appendToString(new StringBuilder(), map, entryFilter_ifNonNull).toString();
}
public static final <K,V> String toString(Map<K,V> map, ValueFilter<Map.Entry<K,V>> entryFilter_ifNonNull, String entry_prefix, String value_prefix, String value_postfix, String entry_postfix, String between) {
return appendToString(new StringBuilder(), map, entryFilter_ifNonNull, entry_prefix, value_prefix, value_postfix, entry_postfix, between).toString();
}
public static final <K,V> StringBuilder appendToString(StringBuilder to_appendTo, Map<K,V> map, ValueFilter<Map.Entry<K,V>> entryFilter_ifNonNull) {
return appendToString(to_appendTo, map, entryFilter_ifNonNull, " - ", null, null, null, LINE_SEP);
}
public static final <K,V> StringBuilder appendToString(StringBuilder to_appendTo, Map<K,V> map, ValueFilter<Map.Entry<K,V>> entryFilter_ifNonNull, String entry_prefix, String value_prefix, String value_postfix, String entry_postfix, String between) {
if(value_prefix == null) {
value_prefix = "";
}
if(value_postfix == null) {
value_postfix = "";
}
if(between == null) {
between = "";
}
Iterator<Map.Entry<K,V>> itr = map.entrySet().iterator();
while(itr.hasNext()) {
Map.Entry<K,V> entry = itr.next();
if(entryFilter_ifNonNull != null && !entryFilter_ifNonNull.doAccept(entry)) {
continue;
}
to_appendTo.append(entry.getKey()).append("=").
append(value_prefix).append(entry.getValue()).append(value_postfix);
if(itr.hasNext()) {
to_appendTo.append(between);
}
}
return to_appendTo;
}
/**
<p>YYY</p>
@exception UnsupportedOperationException If {@code put} is unsupported by {@code map_withMutableListValues}.
*/
public static final <M extends Comparable<? super M>,K> Map<K,List<M>> getWithModifiedListValues(Map<K,List<M>> map_withMutableListValues, SortListValues sort, ImmutableValues immutable) {
try {
if(sort.doNotSort()) {
if(immutable.isYes()) {
for (Map.Entry<K,List<M>> entry : map_withMutableListValues.entrySet()) {
map_withMutableListValues.put(entry.getKey(), Collections.<M>unmodifiableList(entry.getValue()));
}
}
return map_withMutableListValues;
}
if(sort.doSortOriginal()) {
if(immutable.isYes()) {
for (Map.Entry<K,List<M>> entry : map_withMutableListValues.entrySet()) {
List<M> list = entry.getValue();
Collections.sort(list);
map_withMutableListValues.put(entry.getKey(),
Collections.<M>unmodifiableList(list));
}
} else {
for (Map.Entry<K,List<M>> entry : map_withMutableListValues.entrySet()) {
List<M> list = entry.getValue();
Collections.sort(list);
map_withMutableListValues.put(entry.getKey(), list);
}
}
return map_withMutableListValues;
}
if(sort.doSortDuplicate()) {
if(immutable.isYes()) {
for (Map.Entry<K,List<M>> entry : map_withMutableListValues.entrySet()) {
List<M> lOrig = entry.getValue();
List<M> lNew = null;
if(lOrig != null) {
lNew = new ArrayList<M>(lOrig.size());
lNew.addAll(lOrig);
Collections.sort(lNew);
lNew = Collections.<M>unmodifiableList(lNew);
}
map_withMutableListValues.put(entry.getKey(), lNew);
}
} else {
for (Map.Entry<K,List<M>> entry : map_withMutableListValues.entrySet()) {
List<M> lOrig = entry.getValue();
List<M> lNew = null;
if(lOrig != null) {
lNew = new ArrayList<M>(lOrig.size());
lNew.addAll(lOrig);
Collections.sort(lNew);
}
map_withMutableListValues.put(entry.getKey(), lNew);
}
}
return map_withMutableListValues;
}
} catch(RuntimeException rx) {
CrashIfObject.nnull(map_withMutableListValues, "map_withMutableListValues", null);
CrashIfObject.nnull(sort, "sort", null);
throw CrashIfObject.nullOrReturnCause(immutable, "immutable", null, rx);
}
throw new IllegalStateException("Unknown value(s) for SortListValues and/or ImmutableValues: sort=" + sort + ", immutable=" + immutable);
}
public static final <T,K> Map<K,List<T>> unmodifiableListValues(Map<K,List<T>> map_withMutableListValues) {
try {
for (Map.Entry<K,List<T>> entry : map_withMutableListValues.entrySet()) {
map_withMutableListValues.put(entry.getKey(), Collections.<T>unmodifiableList(entry.getValue()));
}
return map_withMutableListValues;
} catch(RuntimeException rx) {
throw CrashIfObject.nullOrReturnCause(map_withMutableListValues, "map_withMutableListValues", null, rx);
}
}
public static final <K,V> V getValueCrashIfUnknownKey(Map<K,V> map, String map_varName, K key, String key_varName) {
V value = null;
try {
value = map.get(key);
} catch(RuntimeException rx) {
throw CrashIfObject.nullOrReturnCause(map, map_varName, null, rx);
}
if(value == null) {
throw new IllegalArgumentException(map_varName + ".containsKey(" + key_varName + ") is false. " + key_varName + "=[" + key + "]");
}
return value;
}
/**
<p>YYY</p>
@exception UnsupportedOperationException If {@code put} is unsupported by {@code to_addTo}.
*/
public static final <K,V> void putOrCrashIfContainsKey(Map<K,V> to_addTo, String map_varName, K key, Null null_key, String key_varName, V value, Null null_value, String value_varName) {
try {
if(to_addTo.containsKey(key)) {
throw new BadDuplicateException("Map=" + map_varName + ", " + key_varName + "=[" + key + "]");
}
} catch(RuntimeException rx) {
throw CrashIfObject.nullOrReturnCause(to_addTo, map_varName, null, rx);
}
CrashIfObject.nnull(null_key, key, key_varName, null);
CrashIfObject.nnull(null_value, value, value_varName, null);
try {
to_addTo.put(key, value);
} catch(UnsupportedOperationException uox) {
throw new UnsupportedOperationException("map_varName=\"" + map_varName + "\"", uox);
}
}
}