com.landawn.abacus.util.Maps Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of abacus-common Show documentation
Show all versions of abacus-common Show documentation
A general programming library in Java/Android. It's easy to learn and simple to use with concise and powerful APIs.
/*
* Copyright (C) 2019 HaiYang Li
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.landawn.abacus.util;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Date;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.function.Supplier;
import com.landawn.abacus.parser.ParserUtil;
import com.landawn.abacus.parser.ParserUtil.BeanInfo;
import com.landawn.abacus.parser.ParserUtil.PropInfo;
import com.landawn.abacus.type.Type;
import com.landawn.abacus.util.Fn.IntFunctions;
import com.landawn.abacus.util.Fn.Suppliers;
import com.landawn.abacus.util.u.Nullable;
import com.landawn.abacus.util.u.Optional;
import com.landawn.abacus.util.u.OptionalBoolean;
import com.landawn.abacus.util.u.OptionalByte;
import com.landawn.abacus.util.u.OptionalChar;
import com.landawn.abacus.util.u.OptionalDouble;
import com.landawn.abacus.util.u.OptionalFloat;
import com.landawn.abacus.util.u.OptionalInt;
import com.landawn.abacus.util.u.OptionalLong;
import com.landawn.abacus.util.u.OptionalShort;
/**
*
* Note: This class includes codes copied from Apache Commons Lang, Google Guava and other open source projects under the Apache License 2.0.
* The methods copied from other libraries/frameworks/projects may be modified in this class.
*
*
* @see com.landawn.abacus.util.N
* @see com.landawn.abacus.util.Iterables
* @see com.landawn.abacus.util.Iterators
* @see com.landawn.abacus.util.Strings
*/
public final class Maps {
private Maps() {
// Utility class.
}
/**
*
* @param
* @param the key type
* @param c
* @param keyMapper
* @return
*/
public static Map create(Collection c, final Function keyMapper) {
N.checkArgNotNull(keyMapper);
if (N.isNullOrEmpty(c)) {
return new HashMap<>();
}
final Map result = N.newHashMap(c.size());
for (T e : c) {
result.put(keyMapper.apply(e), e);
}
return result;
}
/**
*
* @param
* @param the key type
* @param the value type
* @param c
* @param keyMapper
* @param valueExtractor
* @return
*/
public static Map create(Collection c, final Function keyMapper,
final Function valueExtractor) {
N.checkArgNotNull(keyMapper);
N.checkArgNotNull(valueExtractor);
if (N.isNullOrEmpty(c)) {
return new HashMap<>();
}
final Map result = N.newHashMap(c.size());
for (T e : c) {
result.put(keyMapper.apply(e), valueExtractor.apply(e));
}
return result;
}
/**
*
* @param
* @param the key type
* @param the value type
* @param
* @param c
* @param keyMapper
* @param valueExtractor
* @param mapSupplier
* @return
*/
public static > M create(Collection c, final Function keyMapper,
final Function valueExtractor, final IntFunction mapSupplier) {
N.checkArgNotNull(keyMapper);
N.checkArgNotNull(valueExtractor);
N.checkArgNotNull(mapSupplier);
if (N.isNullOrEmpty(c)) {
return mapSupplier.apply(0);
}
final M result = mapSupplier.apply(c.size());
for (T e : c) {
result.put(keyMapper.apply(e), valueExtractor.apply(e));
}
return result;
}
/**
*
* @param
* @param
* @param
* @param
* @param c
* @param keyMapper
* @param valueExtractor
* @param mergeFunction
* @param mapSupplier
* @return
*/
public static > M create(Collection c, final Function keyMapper,
final Function valueExtractor, final BinaryOperator mergeFunction, final IntFunction mapSupplier) {
N.checkArgNotNull(keyMapper);
N.checkArgNotNull(valueExtractor);
N.checkArgNotNull(mergeFunction);
N.checkArgNotNull(mapSupplier);
if (N.isNullOrEmpty(c)) {
return mapSupplier.apply(0);
}
final M result = mapSupplier.apply(c.size());
K key = null;
for (T e : c) {
key = keyMapper.apply(e);
final V oldValue = result.get(key);
if (oldValue == null && !result.containsKey(key)) {
result.put(key, valueExtractor.apply(e));
} else {
result.put(key, mergeFunction.apply(oldValue, valueExtractor.apply(e)));
}
}
return result;
}
/**
*
* @param
* @param the key type
* @param iter
* @param keyMapper
* @return
*/
public static Map create(final Iterator iter, final Function keyMapper) {
N.checkArgNotNull(keyMapper);
if (iter == null) {
return new HashMap<>();
}
final Map result = new HashMap<>();
T e = null;
while (iter.hasNext()) {
e = iter.next();
result.put(keyMapper.apply(e), e);
}
return result;
}
/**
*
* @param
* @param the key type
* @param the value type
* @param iter
* @param keyMapper
* @param valueExtractor
* @return
*/
public static Map create(final Iterator iter, final Function keyMapper,
final Function valueExtractor) {
N.checkArgNotNull(keyMapper);
N.checkArgNotNull(valueExtractor);
if (iter == null) {
return new HashMap<>();
}
final Map result = new HashMap<>();
T e = null;
while (iter.hasNext()) {
e = iter.next();
result.put(keyMapper.apply(e), valueExtractor.apply(e));
}
return result;
}
/**
*
* @param
* @param the key type
* @param the value type
* @param
* @param iter
* @param keyMapper
* @param valueExtractor
* @param mapSupplier
* @return
*/
public static > M create(final Iterator iter, final Function keyMapper,
final Function valueExtractor, final Supplier mapSupplier) {
N.checkArgNotNull(keyMapper);
N.checkArgNotNull(valueExtractor);
N.checkArgNotNull(mapSupplier);
if (iter == null) {
return mapSupplier.get();
}
final M result = mapSupplier.get();
T e = null;
while (iter.hasNext()) {
e = iter.next();
result.put(keyMapper.apply(e), valueExtractor.apply(e));
}
return result;
}
/**
*
* @param
* @param
* @param
* @param
* @param iter
* @param keyMapper
* @param valueExtractor
* @param mergeFunction
* @param mapSupplier
* @return
*/
public static > M create(final Iterator iter, final Function keyMapper,
final Function valueExtractor, final BinaryOperator mergeFunction, final Supplier mapSupplier) {
N.checkArgNotNull(keyMapper);
N.checkArgNotNull(valueExtractor);
N.checkArgNotNull(mergeFunction);
N.checkArgNotNull(mapSupplier);
if (iter == null) {
return mapSupplier.get();
}
final M result = mapSupplier.get();
T e = null;
K key = null;
while (iter.hasNext()) {
e = iter.next();
key = keyMapper.apply(e);
final V oldValue = result.get(key);
if (oldValue == null && !result.containsKey(key)) {
result.put(key, valueExtractor.apply(e));
} else {
result.put(key, mergeFunction.apply(oldValue, valueExtractor.apply(e)));
}
}
return result;
}
/**
*
* @param
* @param
* @param
* @param map
* @param valueMapper
* @return
*/
public static Map create(final Map map, final Function valueMapper) {
N.checkArgNotNull(valueMapper);
if (map == null) {
return new HashMap<>();
}
final Map result = Maps.newTargetMap(map);
for (Map.Entry entry : map.entrySet()) {
result.put(entry.getKey(), valueMapper.apply(entry.getValue()));
}
return result;
}
/**
*
* @param
* @param
* @param
* @param
* @param map
* @param valueMapper
* @param mapSupplier
* @return
*/
public static > M create(final Map map, final Function valueMapper,
final IntFunction mapSupplier) {
N.checkArgNotNull(valueMapper);
N.checkArgNotNull(mapSupplier);
if (map == null) {
return mapSupplier.apply(0);
}
final M result = mapSupplier.apply(map.size());
for (Map.Entry entry : map.entrySet()) {
result.put(entry.getKey(), valueMapper.apply(entry.getValue()));
}
return result;
}
/**
*
*
* @param
* @param the key type
* @param c
* @param keyMapper
* @return
* @deprecated Use {@link #create(Collection,Function)} instead
*/
@Deprecated
public static Map newMap(Collection c, final Function keyMapper) {
return create(c, keyMapper);
}
/**
*
*
* @param
* @param the key type
* @param the value type
* @param c
* @param keyMapper
* @param valueExtractor
* @return
* @deprecated Use {@link #create(Collection,Function,Function)} instead
*/
@Deprecated
public static Map newMap(Collection c, final Function keyMapper,
final Function valueExtractor) {
return create(c, keyMapper, valueExtractor);
}
/**
*
*
* @param
* @param the key type
* @param the value type
* @param
* @param c
* @param keyMapper
* @param valueExtractor
* @param mapSupplier
* @return
* @deprecated Use {@link #create(Collection,Function,Function,IntFunction)} instead
*/
@Deprecated
public static > M newMap(Collection c, final Function keyMapper,
final Function valueExtractor, final IntFunction mapSupplier) {
return create(c, keyMapper, valueExtractor, mapSupplier);
}
/**
*
*
* @param
* @param
* @param
* @param
* @param c
* @param keyMapper
* @param valueExtractor
* @param mergeFunction
* @param mapSupplier
* @return
* @deprecated Use {@link #create(Collection,Function,Function,BinaryOperator,IntFunction)} instead
*/
@Deprecated
public static > M newMap(Collection c, final Function keyMapper,
final Function valueExtractor, final BinaryOperator mergeFunction, final IntFunction mapSupplier) {
return create(c, keyMapper, valueExtractor, mergeFunction, mapSupplier);
}
/**
*
*
* @param
* @param the key type
* @param iter
* @param keyMapper
* @return
* @deprecated Use {@link #create(Iterator,Throwables.Function)} instead
*/
@Deprecated
public static Map newMap(final Iterator iter, final Function keyMapper) {
return create(iter, keyMapper);
}
/**
*
*
* @param
* @param the key type
* @param the value type
* @param iter
* @param keyMapper
* @param valueExtractor
* @return
* @deprecated Use {@link #create(Iterator,Throwables.Function,Function)} instead
*/
@Deprecated
public static Map newMap(final Iterator iter, final Function keyMapper,
final Function valueExtractor) {
return create(iter, keyMapper, valueExtractor);
}
/**
*
*
* @param
* @param the key type
* @param the value type
* @param
* @param iter
* @param keyMapper
* @param valueExtractor
* @param mapSupplier
* @return
* @deprecated Use {@link #create(Iterator,Throwables.Function,Function,Supplier)} instead
*/
@Deprecated
public static > M newMap(final Iterator iter, final Function keyMapper,
final Function valueExtractor, final Supplier mapSupplier) {
return create(iter, keyMapper, valueExtractor, mapSupplier);
}
/**
*
*
* @param
* @param
* @param
* @param
* @param iter
* @param keyMapper
* @param valueExtractor
* @param mergeFunction
* @param mapSupplier
* @return
* @deprecated Use {@link #create(Iterator,Throwables.Function,Function,BinaryOperator,Supplier)} instead
*/
@Deprecated
public static > M newMap(final Iterator iter, final Function keyMapper,
final Function valueExtractor, final BinaryOperator mergeFunction, final Supplier mapSupplier) {
return create(iter, keyMapper, valueExtractor, mergeFunction, mapSupplier);
}
/**
*
* @param
* @param
* @param key
* @param value
* @return
* @deprecated replaced by {@link N#newEntry(Object, Object)}
*/
@Deprecated
public static Map.Entry newEntry(final K key, final V value) {
return N.newEntry(key, value);
}
/**
*
* @param
* @param
* @param key
* @param value
* @return
* @deprecated replaced by {@link N#newImmutableEntry(Object, Object)}
*/
@Deprecated
public static ImmutableEntry newImmutableEntry(final K key, final V value) {
return N.newImmutableEntry(key, value);
}
/**
* New target map.
*
* @param m
* @return
*/
@SuppressWarnings("rawtypes")
static Map newTargetMap(Map m) {
return newTargetMap(m, m == null ? 0 : m.size());
}
/**
* New target map.
*
* @param m
* @param size
* @return
*/
@SuppressWarnings("rawtypes")
static Map newTargetMap(Map m, int size) {
if (m == null) {
return size == 0 ? new HashMap<>() : new HashMap<>(size);
}
if (m instanceof SortedMap) {
return new TreeMap<>(((SortedMap) m).comparator());
}
return N.newMap(m.getClass(), size);
}
/**
* New ordering map.
*
* @param m
* @return
*/
@SuppressWarnings("rawtypes")
static Map newOrderingMap(Map m) {
if (m == null) {
return new HashMap<>();
}
return N.newMap(m.getClass(), m.size());
}
/**
*
*
* @param
* @param
* @param keys
* @param values
* @return
*/
public static Map zip(final Collection keys, final Collection values) {
if (N.isNullOrEmpty(keys) || N.isNullOrEmpty(values)) {
return new HashMap<>();
}
final Iterator keyIter = keys.iterator();
final Iterator valueIter = values.iterator();
final int minLen = N.min(keys.size(), values.size());
final Map result = N.newHashMap(minLen);
for (int i = 0; i < minLen; i++) {
result.put(keyIter.next(), valueIter.next());
}
return result;
}
/**
*
*
* @param
* @param
* @param
* @param keys
* @param values
* @param mapSupplier
* @return
*/
public static > Map zip(final Collection keys, final Collection values,
final IntFunction mapSupplier) {
if (N.isNullOrEmpty(keys) || N.isNullOrEmpty(values)) {
return new HashMap<>();
}
final Iterator keyIter = keys.iterator();
final Iterator valueIter = values.iterator();
final int minLen = N.min(keys.size(), values.size());
final Map result = mapSupplier.apply(minLen);
for (int i = 0; i < minLen; i++) {
result.put(keyIter.next(), valueIter.next());
}
return result;
}
/**
*
*
* @param
* @param
* @param
* @param keys
* @param values
* @param mergeFunction
* @param mapSupplier
* @return
*/
public static > Map zip(final Collection keys, final Collection values,
final BinaryOperator mergeFunction, final IntFunction mapSupplier) {
if (N.isNullOrEmpty(keys) || N.isNullOrEmpty(values)) {
return new HashMap<>();
}
final Iterator keyIter = keys.iterator();
final Iterator valueIter = values.iterator();
final int minLen = N.min(keys.size(), values.size());
final Map result = mapSupplier.apply(minLen);
for (int i = 0; i < minLen; i++) {
result.merge(keyIter.next(), valueIter.next(), mergeFunction);
}
return result;
}
/**
*
* @param the key type
* @param the value type
* @param map
* @param key
* @return
*/
public static Nullable get(final Map map, final K key) {
if (N.isNullOrEmpty(map)) {
return Nullable.empty();
}
final V val = map.get(key);
if (val != null || map.containsKey(key)) {
return Nullable.of(val);
} else {
return Nullable.empty();
}
}
/**
* Returns the value to which the specified key is mapped, or {@code defaultValue} if this map contains no mapping for the key.
*
* @param the key type
* @param the value type
* @param map
* @param key
* @param defaultValue
* @return
*/
public static V getOrDefault(final Map map, final K key, final V defaultValue) {
if (N.isNullOrEmpty(map)) {
return defaultValue;
}
final V val = map.get(key);
if (val != null || map.containsKey(key)) {
return val;
} else {
return defaultValue;
}
}
/**
* Returns the value to which the specified key is mapped if it's not {@code null},
* or {@code defaultForNull} if this map contains no mapping for the key or it's {@code null}.
*
* @param
* @param
* @param map
* @param key
* @param defaultForNull to return if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
* @return
*/
public static V getOrDefaultIfNull(final Map map, final K key, final V defaultForNull) {
if (N.isNullOrEmpty(map)) {
return defaultForNull;
}
final V val = map.get(key);
if (val == null) {
return defaultForNull;
} else {
return val;
}
}
/**
* Returns an empty {@code OptionalBoolean} if the specified {@code map} is empty, or no value found by the specified {@code key}, or the value is {@code null}.
*
* @param
* @param map
* @param key
* @return
*/
public static OptionalBoolean getBoolean(final Map map, final K key) {
if (N.isNullOrEmpty(map)) {
return OptionalBoolean.empty();
}
final Object val = map.get(key);
if (val == null) {
return OptionalBoolean.empty();
} else if (val instanceof Boolean) {
return OptionalBoolean.of((Boolean) val);
} else {
return OptionalBoolean.of(N.parseBoolean(N.toString(val)));
}
}
/**
* Returns the mapped {@code boolean} or a boolean converted from String.
* {@code defaultForNull} is returned if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
*
* @param
* @param map
* @param key
* @param defaultForNull to return if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
* @return
*/
public static boolean getBoolean(final Map map, final K key, final boolean defaultForNull) {
if (N.isNullOrEmpty(map)) {
return defaultForNull;
}
final Object val = map.get(key);
if (val == null) {
return defaultForNull;
} else if (val instanceof Boolean) {
return (Boolean) val;
} else {
return N.parseBoolean(N.toString(val));
}
}
/**
* Returns an empty {@code OptionalChar} if the specified {@code map} is empty, or no value found by the specified {@code key}, or the value is {@code null}.
*
* @param
* @param map
* @param key
* @return
*/
public static OptionalChar getChar(final Map map, final K key) {
if (N.isNullOrEmpty(map)) {
return OptionalChar.empty();
}
final Object val = map.get(key);
if (val == null) {
return OptionalChar.empty();
} else if (val instanceof Character) {
return OptionalChar.of(((Character) val));
} else {
return OptionalChar.of(N.parseChar(N.toString(val)));
}
}
/**
* Returns the mapped {@code char} or a char converted from String.
* {@code defaultForNull} is returned if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
*
* @param
* @param map
* @param key
* @param defaultForNull to return if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
* @return
*/
public static char getChar(final Map map, final K key, final char defaultForNull) {
if (N.isNullOrEmpty(map)) {
return defaultForNull;
}
final Object val = map.get(key);
if (val == null) {
return defaultForNull;
} else if (val instanceof Character) {
return (Character) val;
} else {
return N.parseChar(N.toString(val));
}
}
/**
* Returns an empty {@code OptionalByte} if the specified {@code map} is empty, or no value found by the specified {@code key}, or the value is {@code null}.
*
* @param
* @param map
* @param key
* @return
*/
public static OptionalByte getByte(final Map map, final K key) {
if (N.isNullOrEmpty(map)) {
return OptionalByte.empty();
}
final Object val = map.get(key);
if (val == null) {
return OptionalByte.empty();
} else if (val instanceof Number) {
return OptionalByte.of(((Number) val).byteValue());
} else {
return OptionalByte.of(Numbers.toByte(N.toString(val)));
}
}
/**
* Returns the mapped {@code byte} or a byte converted from String.
* {@code defaultForNull} is returned if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
*
* @param
* @param map
* @param key
* @param defaultForNull to return if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
* @return
*/
public static byte getByte(final Map map, final K key, final byte defaultForNull) {
if (N.isNullOrEmpty(map)) {
return defaultForNull;
}
final Object val = map.get(key);
if (val == null) {
return defaultForNull;
} else if (val instanceof Number) {
return ((Number) val).byteValue();
} else {
return Numbers.toByte(N.toString(val));
}
}
/**
* Returns an empty {@code OptionalShort} if the specified {@code map} is empty, or no value found by the specified {@code key}, or the value is {@code null}.
*
* @param
* @param map
* @param key
* @return
*/
public static OptionalShort getShort(final Map map, final K key) {
if (N.isNullOrEmpty(map)) {
return OptionalShort.empty();
}
final Object val = map.get(key);
if (val == null) {
return OptionalShort.empty();
} else if (val instanceof Number) {
return OptionalShort.of(((Number) val).shortValue());
} else {
return OptionalShort.of(Numbers.toShort(N.toString(val)));
}
}
/**
* Returns the mapped {@code short} or a short converted from String.
* {@code defaultForNull} is returned if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
*
* @param
* @param map
* @param key
* @param defaultForNull to return if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
* @return
*/
public static short getShort(final Map map, final K key, final short defaultForNull) {
if (N.isNullOrEmpty(map)) {
return defaultForNull;
}
final Object val = map.get(key);
if (val == null) {
return defaultForNull;
} else if (val instanceof Number) {
return ((Number) val).shortValue();
} else {
return Numbers.toShort(N.toString(val));
}
}
/**
* Returns an empty {@code OptionalInt} if the specified {@code map} is empty, or no value found by the specified {@code key}, or the value is {@code null}.
*
* @param
* @param map
* @param key
* @return
*/
public static OptionalInt getInt(final Map map, final K key) {
if (N.isNullOrEmpty(map)) {
return OptionalInt.empty();
}
final Object val = map.get(key);
if (val == null) {
return OptionalInt.empty();
} else if (val instanceof Number) {
return OptionalInt.of(((Number) val).intValue());
} else {
return OptionalInt.of(Numbers.toInt(N.toString(val)));
}
}
/**
* Returns the mapped {@code integer} or an integer converted from String.
* {@code defaultForNull} is returned if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
*
* @param
* @param map
* @param key
* @param defaultForNull to return if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
* @return
*/
public static int getInt(final Map map, final K key, final int defaultForNull) {
if (N.isNullOrEmpty(map)) {
return defaultForNull;
}
final Object val = map.get(key);
if (val == null) {
return defaultForNull;
} else if (val instanceof Number) {
return ((Number) val).intValue();
} else {
return Numbers.toInt(N.toString(val));
}
}
/**
* Returns an empty {@code OptionalLong} if the specified {@code map} is empty, or no value found by the specified {@code key}, or the value is {@code null}.
*
* @param
* @param map
* @param key
* @return
*/
public static OptionalLong getLong(final Map map, final K key) {
if (N.isNullOrEmpty(map)) {
return OptionalLong.empty();
}
final Object val = map.get(key);
if (val == null) {
return OptionalLong.empty();
} else if (val instanceof Number) {
return OptionalLong.of(((Number) val).longValue());
} else {
return OptionalLong.of(Numbers.toLong(N.toString(val)));
}
}
/**
* Returns the mapped {@code long} or a long converted from String.
* {@code defaultForNull} is returned if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
*
* @param
* @param map
* @param key
* @param defaultForNull to return if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
* @return
*/
public static long getLong(final Map map, final K key, final long defaultForNull) {
if (N.isNullOrEmpty(map)) {
return defaultForNull;
}
final Object val = map.get(key);
if (val == null) {
return defaultForNull;
} else if (val instanceof Number) {
return ((Number) val).longValue();
} else {
return Numbers.toLong(N.toString(val));
}
}
/**
* Returns an empty {@code OptionalFloat} if the specified {@code map} is empty, or no value found by the specified {@code key}, or the value is {@code null}.
*
* @param
* @param map
* @param key
* @return
*/
public static OptionalFloat getFloat(final Map map, final K key) {
if (N.isNullOrEmpty(map)) {
return OptionalFloat.empty();
}
final Object val = map.get(key);
if (val == null) {
return OptionalFloat.empty();
} else {
return OptionalFloat.of(Numbers.toFloat(val));
}
}
/**
* Returns the mapped {@code float} or a float converted from String.
* {@code defaultForNull} is returned if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
*
* @param
* @param map
* @param key
* @param defaultForNull to return if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
* @return
*/
public static float getFloat(final Map map, final K key, final float defaultForNull) {
if (N.isNullOrEmpty(map)) {
return defaultForNull;
}
final Object val = map.get(key);
if (val == null) {
return defaultForNull;
} else {
return Numbers.toFloat(val);
}
}
/**
* Returns an empty {@code OptionalDouble} if the specified {@code map} is empty, or no value found by the specified {@code key}, or the value is {@code null}.
*
* @param
* @param map
* @param key
* @return
*/
public static OptionalDouble getDouble(final Map map, final K key) {
if (N.isNullOrEmpty(map)) {
return OptionalDouble.empty();
}
final Object val = map.get(key);
if (val == null) {
return OptionalDouble.empty();
} else {
return OptionalDouble.of(Numbers.toDouble(val));
}
}
/**
* Returns the mapped {@code double} or a double converted from String.
* {@code defaultForNull} is returned if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
*
* @param
* @param map
* @param key
* @param defaultForNull to return if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
* @return
*/
public static double getDouble(final Map map, final K key, final double defaultForNull) {
if (N.isNullOrEmpty(map)) {
return defaultForNull;
}
final Object val = map.get(key);
if (val == null) {
return defaultForNull;
} else {
return Numbers.toDouble(val);
}
}
/**
* Returns an empty {@code Optional} if the specified {@code map} is empty, or no value found by the specified {@code key}, or the value is {@code null}.
*
* @param
* @param map
* @param key
* @return
*/
public static Optional getString(final Map map, final K key) {
if (N.isNullOrEmpty(map)) {
return Optional.empty();
}
final Object val = map.get(key);
if (val == null) {
return Optional.empty();
} else if (val instanceof String) {
return Optional.of((String) val);
} else {
return Optional.of(N.stringOf(val));
}
}
/**
* Returns the mapped {@code String} or a {@code String} converted from {@code N.toString(value)}.
* {@code defaultForNull} is returned if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
*
* @param
* @param map
* @param key
* @param defaultForNull to return if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
* @return
*/
public static String getString(final Map map, final K key, final String defaultForNull) {
N.checkArgNotNull(defaultForNull, "defaultForNull");
if (N.isNullOrEmpty(map)) {
return defaultForNull;
}
final Object val = map.get(key);
if (val == null) {
return defaultForNull;
} else if (val instanceof String) {
return (String) val;
} else {
return N.stringOf(val);
}
}
/**
* Returns an empty {@code Optional} if the specified {@code map} is empty, or no value found by the specified {@code key}, or the value is {@code null}.
*
*
* Node: To follow one of general design rules in {@code Abacus}, if there is a conversion behind when the source value is not assignable to the target type, put the {@code targetType} to last parameter of the method.
* Otherwise, put the {@code targetTpye} to the first parameter of the method.
*
* @param
* @param
* @param map
* @param key
* @param targetType
* @return
*/
public static Optional get(final Map map, final K key, final Class targetType) {
if (N.isNullOrEmpty(map)) {
return Optional.empty();
}
final Object val = map.get(key);
if (val == null) {
return Optional.empty();
} else if (targetType.isAssignableFrom(val.getClass())) {
return Optional.of((T) val);
} else {
return Optional.of(N.convert(val, targetType));
}
}
/**
* Returns an empty {@code Optional} if the specified {@code map} is empty, or no value found by the specified {@code key}, or the value is {@code null}.
*
*
* Node: To follow one of general design rules in {@code Abacus}, if there is a conversion behind when the source value is not assignable to the target type, put the {@code targetType} to last parameter of the method.
* Otherwise, put the {@code targetTpye} to the first parameter of the method.
*
* @param
* @param
* @param map
* @param key
* @param targetType
* @return
*/
public static Optional get(final Map map, final K key, final Type targetType) {
if (N.isNullOrEmpty(map)) {
return Optional.empty();
}
final Object val = map.get(key);
if (val == null) {
return Optional.empty();
} else if (targetType.clazz().isAssignableFrom(val.getClass())) {
return Optional.of((T) val);
} else {
return Optional.of(N.convert(val, targetType));
}
}
/**
* Returns the mapped {@code T} or a {@code T} converted from {@code N.valueOf((Class) defaultForNull.getClass(), N.stringOf(val))}.
* {@code defaultForNull} is returned if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
*
* @param
* @param
* @param map
* @param key
* @param defaultForNull to return if the specified {@code map} doesn't contain the specified {@code key} or the mapped value is {@code null}.
* @return
*/
public static T get(final Map map, final K key, final T defaultForNull) {
N.checkArgNotNull(defaultForNull, "defaultForNull");
if (N.isNullOrEmpty(map)) {
return defaultForNull;
}
final Object val = map.get(key);
if (val == null) {
return defaultForNull;
} else if (defaultForNull.getClass().isAssignableFrom(val.getClass())) {
return (T) val;
} else {
return (T) N.convert(val, defaultForNull.getClass());
}
}
/**
* Returns the value to which the specified key is mapped, or
* an empty immutable {@code List} if this map contains no mapping for the key.
*
* @param the key type
* @param
* @param the value type
* @param map
* @param key
* @return
*/
public static > List getOrEmptyList(final Map map, final K key) {
if (N.isNullOrEmpty(map)) {
return N. emptyList();
}
final V val = map.get(key);
if (val != null || map.containsKey(key)) {
return val;
} else {
return N.emptyList();
}
}
/**
* Returns the value to which the specified key is mapped, or
* an empty immutable {@code Set} if this map contains no mapping for the key.
*
* @param the key type
* @param
* @param the value type
* @param map
* @param key
* @return
*/
public static > Set getOrEmptySet(final Map map, final K key) {
if (N.isNullOrEmpty(map)) {
return N. emptySet();
}
final V val = map.get(key);
if (val != null || map.containsKey(key)) {
return val;
} else {
return N.emptySet();
}
}
/**
* Returns the value associated with the specified {@code key} if it exists in the specified {@code map} contains, or the new put {@code List} if it's absent.
*
* @param the key type
* @param
* @param map
* @param key
* @return
*/
public static List getAndPutListIfAbsent(final Map> map, final K key) {
List v = map.get(key);
if (v == null) {
v = new ArrayList<>();
v = map.put(key, v);
}
return v;
}
/**
* Returns the value associated with the specified {@code key} if it exists in the specified {@code map} contains, or the new put {@code Set} if it's absent.
*
* @param the key type
* @param
* @param map
* @param key
* @return
*/
public static Set getAndPutSetIfAbsent(final Map> map, final K key) {
Set v = map.get(key);
if (v == null) {
v = N.newHashSet();
v = map.put(key, v);
}
return v;
}
/**
* Returns the value associated with the specified {@code key} if it exists in the specified {@code map} contains, or the new put {@code Set} if it's absent.
*
* @param the key type
* @param
* @param map
* @param key
* @return
*/
public static Set getAndPutLinkedHashSetIfAbsent(final Map> map, final K key) {
Set v = map.get(key);
if (v == null) {
v = N.newLinkedHashSet();
v = map.put(key, v);
}
return v;
}
/**
* Returns the value associated with the specified {@code key} if it exists in the specified {@code map} contains, or the new put {@code Map} if it's absent.
*
* @param the key type
* @param
* @param
* @param map
* @param key
* @return
*/
public static Map getAndPutMapIfAbsent(final Map> map, final K key) {
Map v = map.get(key);
if (v == null) {
v = new HashMap<>();
v = map.put(key, v);
}
return v;
}
/**
* Returns a list of values of the keys which exist in the specified Map
.
* If the key dosn't exist in the Map
, No value will be added into the returned list.
*
* @param the key type
* @param the value type
* @param map
* @param keys
* @return
*/
public static List getIfPresentForEach(final Map map, final Collection keys) {
if (N.isNullOrEmpty(map) || N.isNullOrEmpty(keys)) {
return new ArrayList<>(0);
}
final List result = new ArrayList<>(keys.size());
V val = null;
for (Object key : keys) {
val = map.get(key);
if (val != null || map.containsKey(key)) {
result.add(val);
}
}
return result;
}
/**
* Gets the or default for each.
*
* @param the key type
* @param the value type
* @param map
* @param keys
* @param defaultValue
* @return
*/
public static List getOrDefaultForEach(final Map map, final Collection keys, final V defaultValue) {
if (N.isNullOrEmpty(keys)) {
return new ArrayList<>(0);
} else if (N.isNullOrEmpty(map)) {
return N.repeat(defaultValue, keys.size());
}
final List result = new ArrayList<>(keys.size());
V val = null;
for (Object key : keys) {
val = map.get(key);
if (val != null || map.containsKey(key)) {
result.add(val);
} else {
result.add(defaultValue);
}
}
return result;
}
/**
*
*
* @param
* @param
* @param map
* @param keys
* @param defaultValue
* @return
*/
public static List getOrDefaultIfNullForEach(final Map map, final Collection keys, final V defaultValue) {
if (N.isNullOrEmpty(keys)) {
return new ArrayList<>(0);
} else if (N.isNullOrEmpty(map)) {
return N.repeat(defaultValue, keys.size());
}
final List result = new ArrayList<>(keys.size());
V val = null;
for (Object key : keys) {
val = map.get(key);
if (val == null) {
result.add(defaultValue);
} else {
result.add(val);
}
}
return result;
}
/**
* Recursively get the values from the specified {@code map} by {@code path}. For example:
*
*
Map map = N.asMap("key1", "val1");
assertEquals("val1", Maps.getByPath(map, "key1"));
map = N.asMap("key1", N.asList("val1"));
assertEquals("val1", Maps.getByPath(map, "key1[0]"));
map = N.asMap("key1", N.asSet("val1"));
assertEquals("val1", Maps.getByPath(map, "key1[0]"));
map = N.asMap("key1", N.asList(N.asLinkedHashSet("val1", "val2")));
assertEquals("val2", Maps.getByPath(map, "key1[0][1]"));
map = N.asMap("key1", N.asSet(N.asList(N.asSet("val1"))));
assertEquals("val1", Maps.getByPath(map, "key1[0][0][0]"));
map = N.asMap("key1", N.asList(N.asLinkedHashSet("val1", N.asMap("key2", "val22"))));
assertEquals("val22", Maps.getByPath(map, "key1[0][1].key2"));
map = N.asMap("key1", N.asList(N.asLinkedHashSet("val1", N.asMap("key2", N.asList("val22", N.asMap("key3", "val33"))))));
assertEquals("val33", Maps.getByPath(map, "key1[0][1].key2[1].key3"));
map = N.asMap("key1", N.asList(N.asLinkedHashSet("val1", N.asMap("key2", N.asList("val22", N.asMap("key3", "val33"))))));
assertNull(Maps.getByPath(map, "key1[0][2].key2[1].key3"));
*
*
*
* @param
* @param map
* @param path
* @return {@code null} if there is no value found by the specified path.
*/
public static T getByPath(final Map map, final String path) {
final Object val = getByPathOrDefault(map, path, N.NULL_MASK);
if (val == N.NULL_MASK) {
return null;
}
return (T) val;
}
/**
*
* @param
* @param map
* @param path
* @param targetType
* @return {@code null} if there is no value found by the specified path.
*/
public static T getByPath(final Map map, final String path, final Class targetType) {
final Object val = getByPathOrDefault(map, path, N.NULL_MASK);
if (val == N.NULL_MASK) {
return null;
}
if (val == null || targetType.isAssignableFrom(val.getClass())) {
return (T) val;
} else {
return N.convert(val, targetType);
}
}
/**
*
* @param
* @param map
* @param path
* @param defaultValue
* @return {@code defaultValue} if there is no value found by the specified path.
* @see #getByPath(Map, String)
*/
@SuppressWarnings("rawtypes")
public static T getByPathOrDefault(final Map map, final String path, final T defaultValue) {
N.checkArgNotNull(defaultValue, "defaultValue");
if (N.isNullOrEmpty(map)) {
return defaultValue;
}
final Class targetType = defaultValue == null || defaultValue == N.NULL_MASK ? null : defaultValue.getClass();
final String[] keys = Strings.split(path, '.');
Map intermediateMap = map;
Collection intermediateColl = null;
String key = null;
for (int i = 0, len = keys.length; i < len; i++) {
key = keys[i];
if (N.isNullOrEmpty(intermediateMap)) {
return defaultValue;
}
if (key.charAt(key.length() - 1) == ']') {
final int[] indexes = Strings.findAllSubstringsBetween(key, "[", "]").stream().mapToInt(Numbers::toInt).toArray();
final int idx = key.indexOf('[');
intermediateColl = (Collection) intermediateMap.get(key.substring(0, idx));
for (int j = 0, idxLen = indexes.length; j < idxLen; j++) {
if (N.isNullOrEmpty(intermediateColl) || intermediateColl.size() <= indexes[j]) {
return defaultValue;
} else {
if (j == idxLen - 1) {
if (i == len - 1) {
final Object ret = N.getElement(intermediateColl, indexes[j]);
if (ret == null || targetType == null || targetType.isAssignableFrom(ret.getClass())) {
return (T) ret;
} else {
return (T) N.convert(ret, targetType);
}
} else {
intermediateMap = (Map) N.getElement(intermediateColl, indexes[j]);
}
} else {
intermediateColl = (Collection) N.getElement(intermediateColl, indexes[j]);
}
}
}
} else {
if (i == len - 1) {
final Object ret = intermediateMap.getOrDefault(key, defaultValue);
if (ret == null || targetType == null || targetType.isAssignableFrom(ret.getClass())) {
return (T) ret;
} else {
return (T) N.convert(ret, targetType);
}
} else {
intermediateMap = (Map) intermediateMap.get(key);
}
}
}
return defaultValue;
}
/**
*
* @param