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; } }