package org.nutz.lang.util;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.nutz.castor.Castors;
import org.nutz.lang.Each;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
/**
* 对于 TreeMap 的一个友好封装
* <p>
* 同 TreeMap 不同的是,如果 get(null),它不会抛错,就是返回 null 或默认值
*
* @author zozoh(zozohtnt@gmail.com)
*/
@SuppressWarnings("serial")
public class NutMap extends LinkedHashMap<String, Object> {
public static NutMap WRAP(Map<String, Object> map) {
if (null == map)
return null;
if (map instanceof NutMap)
return (NutMap) map;
return new NutMap(map);
}
public NutMap() {
super();
}
public NutMap(Map<String, Object> map) {
super();
this.putAll(map);
}
public NutMap(String json) {
super();
this.putAll(Lang.map(json));
}
public int getInt(String key) {
return getInt(key, -1);
}
public int getInt(String key, int dft) {
Object v = get(key);
return null == v ? dft : Castors.me().castTo(v, int.class);
}
public float getFloat(String key) {
return getFloat(key, Float.NaN);
}
public float getFloat(String key, float dft) {
Object v = get(key);
return null == v ? dft : Castors.me().castTo(v, float.class);
}
public long getLong(String key) {
return getLong(key, -1);
}
public long getLong(String key, long dft) {
Object v = get(key);
return null == v ? dft : Castors.me().castTo(v, long.class);
}
public double getDouble(String key) {
return getDouble(key, 0.0);
}
public double getDouble(String key, double dft) {
Object v = get(key);
return null == v ? dft : Castors.me().castTo(v, double.class);
}
public boolean getBoolean(String key) {
return getBoolean(key, false);
}
public boolean getBoolean(String key, boolean dft) {
Object v = get(key);
return null == v ? dft : Castors.me().castTo(v, boolean.class);
}
public String getString(String key) {
return getString(key, null);
}
@SuppressWarnings("rawtypes")
public String getString(String key, String dft) {
Object v = get(key);
if (v == null)
return dft;
if (v instanceof List) {
v = ((List) v).iterator().next();
}
// by wendal : 这还有必要castTo么?
return Castors.me().castTo(v, String.class);
}
public Date getTime(String key) {
return getTime(key, null);
}
public Date getTime(String key, Date dft) {
Object v = get(key);
return null == v ? dft : Castors.me().castTo(v, Date.class);
}
public <T extends Enum<?>> T getEnum(String key, Class<T> classOfEnum) {
String s = getString(key);
if (Strings.isBlank(s))
return null;
return Castors.me().castTo(s, classOfEnum);
}
public boolean isEnum(String key, Enum<?>... eus) {
if (null == eus || eus.length == 0)
return false;
try {
Enum<?> v = getEnum(key, eus[0].getClass());
for (Enum<?> eu : eus)
if (!v.equals(eu))
return false;
return true;
}
catch (Exception e) {
return false;
}
}
public <T> T getAs(String key, Class<T> classOfT) {
return getAs(key, classOfT, null);
}
public <T> T getAs(String key, Class<T> classOfT, T dft) {
Object v = get(key);
return null == v ? dft : Castors.me().castTo(v, classOfT);
}
/**
* 将一个字段转换成列表。因为返回的是容器,所以本函数永远不会返回 null
*
* @param <T>
* @param key
* @param eleType
* @return 列表对象,如果字段不存在或者为空,则返回一个空列表
*/
@SuppressWarnings("unchecked")
public <T> List<T> getList(String key, final Class<T> eleType) {
Object v = get(key);
if (null == v)
return new ArrayList<T>();
if (v instanceof CharSequence) {
return Lang.list(Castors.me().castTo(v, eleType));
}
int len = Lang.length(v);
final List<T> list = new ArrayList<T>(len);
Lang.each(v, new Each<Object>() {
public void invoke(int index, Object ele, int length) {
list.add(Castors.me().castTo(ele, eleType));
}
});
return list;
}
/**
* 将一个字段转换成数组。因为返回的是容器,所以本函数永远不会返回 null
*
* @param <T>
* @param key
* @param eleType
* @return 数组对象,如果字段不存在或者为空,则返回一个空数组
*/
@SuppressWarnings("unchecked")
public <T> T[] getArray(String key, final Class<T> eleType) {
Object v = get(key);
if (null == v)
return (T[]) Array.newInstance(eleType, 0);
if (v instanceof CharSequence) {
return Lang.array(Castors.me().castTo(v, eleType));
}
int len = Lang.length(v);
final Object arr = Array.newInstance(eleType, len);
final int[] i = new int[]{0};
Lang.each(v, new Each<Object>() {
public void invoke(int index, Object ele, int length) {
Array.set(arr, i[0]++, Castors.me().castTo(ele, eleType));
}
});
return (T[]) arr;
}
/**
* 为 Map 增加一个名值对。如果同名已经有值了,那么会将两个值合并成一个列表
*
* @param key
* @param value
*/
@SuppressWarnings("unchecked")
public NutMap addv(String key, Object value) {
Object obj = get(key);
if (null == obj) {
put(key, value);
} else if (obj instanceof List<?>)
((List<Object>) obj).add(value);
else {
List<Object> list = new LinkedList<Object>();
list.add(obj);
list.add(value);
put(key, list);
}
return this;
}
/**
* @deprecated 本函数意义容易发生混淆,已经改名成 addv,下个版将被删除
* @since 1.b.51
*/
public NutMap putv(String key, Object value) {
return addv(key, value);
}
public NutMap setv(String key, Object value) {
this.put(key, value);
return this;
}
}