📄 maputils.java
字号:
out.println("null");
return;
}
if (label != null) {
out.print(label);
out.println(" = ");
}
printIndent(out, lineage.size());
out.println("{");
lineage.push(map);
for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
Object childKey = entry.getKey();
Object childValue = entry.getValue();
if (childValue instanceof Map && !lineage.contains(childValue)) {
verbosePrintInternal(
out,
(childKey == null ? "null" : childKey),
(Map) childValue,
lineage,
debug);
} else {
printIndent(out, lineage.size());
out.print(childKey);
out.print(" = ");
final int lineageIndex = lineage.indexOf(childValue);
if (lineageIndex == -1) {
out.print(childValue);
} else if (lineage.size() - 1 == lineageIndex) {
out.print("(this Map)");
} else {
out.print(
"(ancestor["
+ (lineage.size() - 1 - lineageIndex - 1)
+ "] Map)");
}
if (debug && childValue != null) {
out.print(' ');
out.println(childValue.getClass().getName());
} else {
out.println();
}
}
}
lineage.pop();
printIndent(out, lineage.size());
out.println(debug ? "} " + map.getClass().getName() : "}");
}
/**
* Writes indentation to the given stream.
*
* @param out the stream to indent
*/
private static void printIndent(final PrintStream out, final int indent) {
for (int i = 0; i < indent; i++) {
out.print(INDENT_STRING);
}
}
// Misc
//-----------------------------------------------------------------------
/**
* Inverts the supplied map returning a new HashMap such that the keys of
* the input are swapped with the values.
* <p>
* This operation assumes that the inverse mapping is well defined.
* If the input map had multiple entries with the same value mapped to
* different keys, the returned map will map one of those keys to the
* value, but the exact key which will be mapped is undefined.
*
* @param map the map to invert, may not be null
* @return a new HashMap containing the inverted data
* @throws NullPointerException if the map is null
*/
public static Map invertMap(Map map) {
Map out = new HashMap(map.size());
for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
out.put(entry.getValue(), entry.getKey());
}
return out;
}
//-----------------------------------------------------------------------
/**
* Protects against adding null values to a map.
* <p>
* This method checks the value being added to the map, and if it is null
* it is replaced by an empty string.
* <p>
* This could be useful if the map does not accept null values, or for
* receiving data from a source that may provide null or empty string
* which should be held in the same way in the map.
* <p>
* Keys are not validated.
*
* @param map the map to add to, may not be null
* @param key the key
* @param value the value, null converted to ""
* @throws NullPointerException if the map is null
*/
public static void safeAddToMap(Map map, Object key, Object value) throws NullPointerException {
if (value == null) {
map.put(key, "");
} else {
map.put(key, value);
}
}
//-----------------------------------------------------------------------
/**
* Puts all the keys and values from the specified array into the map.
* <p>
* This method is an alternative to the {@link java.util.Map#putAll(java.util.Map)}
* method and constructors. It allows you to build a map from an object array
* of various possible styles.
* <p>
* If the first entry in the object array implements {@link java.util.Map.Entry}
* or {@link KeyValue} then the key and value are added from that object.
* If the first entry in the object array is an object array itself, then
* it is assumed that index 0 in the sub-array is the key and index 1 is the value.
* Otherwise, the array is treated as keys and values in alternate indices.
* <p>
* For example, to create a color map:
* <pre>
* Map colorMap = MapUtils.putAll(new HashMap(), new String[][] {
* {"RED", "#FF0000"},
* {"GREEN", "#00FF00"},
* {"BLUE", "#0000FF"}
* });
* </pre>
* or:
* <pre>
* Map colorMap = MapUtils.putAll(new HashMap(), new String[] {
* "RED", "#FF0000",
* "GREEN", "#00FF00",
* "BLUE", "#0000FF"
* });
* </pre>
* or:
* <pre>
* Map colorMap = MapUtils.putAll(new HashMap(), new Map.Entry[] {
* new DefaultMapEntry("RED", "#FF0000"),
* new DefaultMapEntry("GREEN", "#00FF00"),
* new DefaultMapEntry("BLUE", "#0000FF")
* });
* </pre>
*
* @param map the map to populate, must not be null
* @param array an array to populate from, null ignored
* @return the input map
* @throws NullPointerException if map is null
* @throws IllegalArgumentException if sub-array or entry matching used and an
* entry is invalid
* @throws ClassCastException if the array contents is mixed
* @since Commons Collections 3.2
*/
public static Map putAll(Map map, Object[] array) {
map.size(); // force NPE
if (array == null || array.length == 0) {
return map;
}
Object obj = array[0];
if (obj instanceof Map.Entry) {
for (int i = 0; i < array.length; i++) {
Map.Entry entry = (Map.Entry) array[i];
map.put(entry.getKey(), entry.getValue());
}
} else if (obj instanceof KeyValue) {
for (int i = 0; i < array.length; i++) {
KeyValue keyval = (KeyValue) array[i];
map.put(keyval.getKey(), keyval.getValue());
}
} else if (obj instanceof Object[]) {
for (int i = 0; i < array.length; i++) {
Object[] sub = (Object[]) array[i];
if (sub == null || sub.length < 2) {
throw new IllegalArgumentException("Invalid array element: " + i);
}
map.put(sub[0], sub[1]);
}
} else {
for (int i = 0; i < array.length - 1;) {
map.put(array[i++], array[i++]);
}
}
return map;
}
//-----------------------------------------------------------------------
/**
* Null-safe check if the specified map is empty.
* <p>
* Null returns true.
*
* @param map the map to check, may be null
* @return true if empty or null
* @since Commons Collections 3.2
*/
public static boolean isEmpty(Map map) {
return (map == null || map.isEmpty());
}
/**
* Null-safe check if the specified map is not empty.
* <p>
* Null returns false.
*
* @param map the map to check, may be null
* @return true if non-null and non-empty
* @since Commons Collections 3.2
*/
public static boolean isNotEmpty(Map map) {
return !MapUtils.isEmpty(map);
}
// Map decorators
//-----------------------------------------------------------------------
/**
* Returns a synchronized map backed by the given map.
* <p>
* You must manually synchronize on the returned buffer's iterator to
* avoid non-deterministic behavior:
*
* <pre>
* Map m = MapUtils.synchronizedMap(myMap);
* Set s = m.keySet(); // outside synchronized block
* synchronized (m) { // synchronized on MAP!
* Iterator i = s.iterator();
* while (i.hasNext()) {
* process (i.next());
* }
* }
* </pre>
*
* This method uses the implementation in {@link java.util.Collections Collections}.
*
* @param map the map to synchronize, must not be null
* @return a synchronized map backed by the given map
* @throws IllegalArgumentException if the map is null
*/
public static Map synchronizedMap(Map map) {
return Collections.synchronizedMap(map);
}
/**
* Returns an unmodifiable map backed by the given map.
* <p>
* This method uses the implementation in the decorators subpackage.
*
* @param map the map to make unmodifiable, must not be null
* @return an unmodifiable map backed by the given map
* @throws IllegalArgumentException if the map is null
*/
public static Map unmodifiableMap(Map map) {
return UnmodifiableMap.decorate(map);
}
/**
* Returns a predicated (validating) map backed by the given map.
* <p>
* Only objects that pass the tests in the given predicates can be added to the map.
* Trying to add an invalid object results in an IllegalArgumentException.
* Keys must pass the key predicate, values must pass the value predicate.
* It is important not to use the original map after invoking this method,
* as it is a backdoor for adding invalid objects.
*
* @param map the map to predicate, must not be null
* @param keyPred the predicate for keys, null means no check
* @param valuePred the predicate for values, null means no check
* @return a predicated map backed by the given map
* @throws IllegalArgumentException if the Map is null
*/
public static Map predicatedMap(Map map, Predicate keyPred, Predicate valuePred) {
return PredicatedMap.decorate(map, keyPred, valuePred);
}
/**
* Returns a typed map backed by the given map.
* <p>
* Only keys and values of the specified types can be added to the map.
*
* @param map the map to limit to a specific type, must not be null
* @param keyType the type of keys which may be added to the map, must not be null
* @param valueType the type of values which may be added to the map, must not be null
* @return a typed map backed by the specified map
* @throws IllegalArgumentException if the Map or Class is null
*/
public static Map typedMap(Map map, Class keyType, Class valueType) {
return TypedMap.decorate(map, keyType, valueType);
}
/**
* Returns a transformed map backed by the given map.
* <p>
* This method returns a new map (decorating the specified map) that
* will transform any new entries added to it.
* Existing entries in the specified map will not be transformed.
* If you want that behaviour, see {@link TransformedMap#decorateTransform}.
* <p>
* Each object is passed through the transformers as it is added to the
* Map. It is important not to use the original map after invoking this
* method, as it is a backdoor for adding untransformed objects.
* <p>
* If there are any elements already in the map being decorated, they
* are NOT transformed.
*
* @param map the map to transform, must not be null, typically empty
* @param keyTransformer the transformer for the map keys, null means no transformation
* @param valueTransformer the transformer for the map values, null means no transformation
* @return a transformed map backed by the given map
* @throws IllegalArgumentException if the Map is null
*/
public static Map transformedMap(Map map, Transformer keyTransformer, Transformer valueTransformer) {
return TransformedMap.decorate(map, keyTransformer, valueTransformer);
}
/**
* Returns a fixed-sized map backed by the given map.
* Elements may not be added or removed from the returned map, but
* existing elements can be changed (for instance, via the
* {@link Map#put(Object,Object)} method).
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -