com.iqiny.silly.common.util.SillyMapUtils Maven / Gradle / Ivy
The newest version!
/*
* Copyright iqiny.com
*
* https://gitee.com/iqiny/silly
*
* project name:silly-common
* project description:top silly project pom.xml file
*/
package com.iqiny.silly.common.util;
import com.iqiny.silly.common.SillyConstant;
import com.iqiny.silly.common.exception.SillyException;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* MapUtils
*/
public abstract class SillyMapUtils {
/**
* 属性名称拼接串
*/
public static final String FIELD_NAME_APPEND = ".";
/**
* 属性名称裁剪串
*/
public static final String FIELD_NAME_SPLIT = "\\.";
/**
* 设置Map 键-值
*
* @param map
* @param key 支持深层命名如:entity.user.loginName / entity[1][office].code
* @param value
* @return 原先数据值 或 null
*/
public static T put(final Map, ?> map, String key, Object value) {
List names = resolvingFieldName(key);
return put(map, names, value);
}
public static T putLayerKey(final Map, ?> map, Object value, Serializable... layerKeys) {
return put(map, new ArrayList<>(Arrays.asList(layerKeys)), value);
}
@SuppressWarnings("all")
public static T put(final Map, ?> map, List names, Object value) {
if (map == null) {
return null;
}
if (names.isEmpty()) {
return null;
}
synchronized (map) {
Serializable preName = names.get(0);
Object preObj = map;
for (int i = 0; i < names.size(); i++) {
Object currentObj = null;
boolean lastNameFlag = (names.size() == (i + 1));
Serializable name = names.get(i);
if (!lastNameFlag) {
// 获取值并设置空值过程
if (name instanceof Integer) {
if (preObj instanceof List) {
// 若为List 则设置值
Integer index = (Integer) name;
List list = (List) preObj;
if (index >= list.size()) {
currentObj = null;
} else {
currentObj = list.get(index);
}
} else {
// 若不为List 则抛出异常
throw new SillyException("数据设置值数据类型错误应为 List ==> " + currentObj.getClass());
}
} else if (preObj instanceof Map) {
Map objMap = (Map) preObj;
currentObj = objMap.get(name);
} else if (name instanceof String) {
String fieldName = (String) name;
try {
// 其他类型,通过反射设置值
Class> aClass = preObj.getClass();
Field declaredField = aClass.getDeclaredField(fieldName);
declaredField.setAccessible(true);
currentObj = declaredField.get(preObj);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new SillyException(e.getMessage(), e);
}
} else {
throw new SillyException("Map值设置数据类型不支持 key:" + name);
}
// 设置空值情况
if (currentObj == null) {
// 根据下一属性,确定数据类型
Serializable nextName = names.get(i + 1);
if (nextName instanceof Integer) {
currentObj = new ArrayList<>();
} else {
currentObj = new LinkedHashMap<>();
}
if (name instanceof Integer) {
List list = (List) preObj;
Integer index = (Integer) name;
int e = index - list.size();
if (e > 0) {
for (int j = 0; j <= e; j++) {
list.add(null);
}
}
list.set(index, currentObj);
} else {
Map objMap = (Map) preObj;
objMap.put(name, currentObj);
}
}
} else {
// 最终值设置
if (name instanceof Integer && preObj instanceof List) {
List list = (List) preObj;
Integer index = (Integer) name;
int e = index - list.size();
if (e > 0) {
for (int j = 0; j <= e; j++) {
list.add(null);
}
}
return (T) list.set(index, value);
} else if (preObj instanceof Map) {
Map objMap = (Map) preObj;
return (T) objMap.put(name, value);
} else if (name instanceof String) {
String fieldName = (String) name;
try {
// 其他类型,通过反射设置值
Class> aClass = preObj.getClass();
Field declaredField = aClass.getDeclaredField(fieldName);
declaredField.setAccessible(true);
Object o = declaredField.get(preObj);
declaredField.set(preObj, value);
return (T) o;
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new SillyException("数据类型不支持" + preObj.getClass() + " 错误:" + e.getMessage(), e);
}
} else {
throw new SillyException("Map值设置数据类型不支持 lastKey:" + name);
}
}
preObj = currentObj;
preName = name;
}
}
return null;
}
/**
* 删除Map 键-值
*
* @param key 支持深层命名如:entity.user.loginName / entity[1][office].code
* @return 原先数据值 或 null
*/
public static T remove(final Map, ?> map, String key) {
List names = resolvingFieldName(key);
return remove(map, names);
}
public static T removeLayerKey(final Map, ?> map, Serializable... layerKey) {
return remove(map, new ArrayList<>(Arrays.asList(layerKey)));
}
@SuppressWarnings("all")
public static T remove(final Map, ?> map, List names) {
if (map == null) {
return null;
}
if (names.isEmpty()) {
return null;
}
synchronized (map) {
Serializable preName = names.get(0);
Object preObj = map;
for (int i = 0; i < names.size(); i++) {
Object currentObj = null;
boolean lastNameFlag = (names.size() == (i + 1));
Serializable name = names.get(i);
if (!lastNameFlag) {
// 获取值
if (name instanceof Integer) {
if (preObj instanceof List) {
// 若为List 则设置值
Integer index = (Integer) name;
List list = (List) preObj;
if (index >= list.size()) {
return null;
} else {
currentObj = list.get(index);
}
} else {
// 若不为List 则抛出异常
throw new SillyException("数据设置值数据类型错误应为 List ==> " + currentObj.getClass());
}
} else if (preObj instanceof Map) {
Map objMap = (Map) preObj;
currentObj = objMap.get(name);
} else if (name instanceof String) {
String fieldName = (String) name;
try {
// 其他类型,通过反射设置值
Class> aClass = preObj.getClass();
Field declaredField = aClass.getDeclaredField(fieldName);
declaredField.setAccessible(true);
currentObj = declaredField.get(preObj);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new SillyException(e.getMessage(), e);
}
} else {
throw new SillyException("Map值设置数据类型不支持 key:" + name);
}
// 设置空值情况
if (currentObj == null) {
return null;
}
} else {
// 最终值设置
if (name instanceof Integer && preObj instanceof List) {
List list = (List) preObj;
Integer index = (Integer) name;
Object o = list.get(index);
list.remove(index);
return (T) o;
} else if (preObj instanceof Map) {
Map objMap = (Map) preObj;
return (T) objMap.remove(name);
} else if (name instanceof String) {
String fieldName = (String) name;
try {
// 其他类型,通过反射设置值
Class> aClass = preObj.getClass();
Field declaredField = aClass.getDeclaredField(fieldName);
declaredField.setAccessible(true);
Object o = declaredField.get(preObj);
declaredField.set(preObj, null);
return (T) o;
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new SillyException("数据类型不支持" + preObj.getClass() + " 错误:" + e.getMessage(), e);
}
} else {
throw new SillyException("Map值设置数据类型不支持 lastKey:" + name);
}
}
preObj = currentObj;
preName = name;
}
}
return null;
}
/**
* 判断Map中是否存在此KEY
*
* @param key 支持深层命名如:entity.user.loginName / entity[1][office].code
* @return 是否存在KEY
*/
public static boolean containsKey(final Map, ?> map, String key) {
List names = resolvingFieldName(key);
return containsKey(map, names);
}
public static boolean containsLayerKey(final Map, ?> map, Serializable... layerKeys) {
return containsKey(map, new ArrayList<>(Arrays.asList(layerKeys)));
}
public static boolean containsKey(final Map, ?> map, List names) {
if (map == null) {
return false;
}
if (names.isEmpty()) {
return false;
}
if (names.size() == 1) {
return map.containsKey(names.get(0));
}
Object currentKey = names.remove(names.size() - 1);
Object currentObj = getObj(map, names, null);
if (currentKey instanceof Integer) {
if (currentObj instanceof List) {
List list = (List) currentObj;
Integer i = (Integer) currentKey;
return list.size() > i;
} else {
return false;
}
} else if (currentObj instanceof Map) {
Map objMap = (Map) currentObj;
return objMap.containsKey(currentKey);
} else if (currentKey instanceof String) {
String fieldName = (String) currentKey;
// 其他类型,通过反射设置值
Class> aClass = currentObj.getClass();
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
if (Objects.equals(declaredField.getName(), fieldName)) {
return true;
}
}
return false;
} else {
throw new SillyException("Map值设置数据类型不支持 lastKey:" + currentKey);
}
}
public static Map beanToMap(Object beanObj, String... ignore) {
if (beanObj instanceof Map) {
return new TreeMap<>((Map) beanObj);
}
return beanToMap(beanObj, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), ignore);
}
/**
* 使用Introspector,对象转换为map集合
*/
public static Map beanToMap(Object beanObj, DateFormat df, String... ignore) {
if (null == beanObj) {
return null;
}
List ignorList = new ArrayList<>();
if (ignore != null) {
ignorList = Arrays.asList(ignore);
}
TreeMap map = new TreeMap<>();
try {
BeanInfo beanInfo = Introspector.getBeanInfo(beanObj.getClass());
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor property : propertyDescriptors) {
String key = property.getName();
if (ignorList.contains(key) || key.compareToIgnoreCase("class") == 0) {
continue;
}
Method getter = property.getReadMethod();
Object value = getter != null ? getter.invoke(beanObj) : null;
if (value instanceof Date && df != null) {
value = df.format(value);
}
map.put(key, value);
}
return map;
} catch (Exception ex) {
throw new SillyException(ex.getMessage());
}
}
/**
* 使用 JSON 将Map 转为 bean
*/
public static T mapToBean(Map map, Class tClass) {
return mapToBean(map, tClass, (String[]) null);
}
/**
* 使用 JSON 将Map 转为 bean
*/
public static T mapToBean(Map map, Class tClass, String... ignore) {
if (map == null) {
return null;
}
if (ignore != null) {
List ignoreList = Arrays.asList(ignore);
ignoreList.forEach(map::remove);
}
String jsonString = SillyObjectUtil.objectToJsonString(map);
return SillyObjectUtil.jsonToObject(jsonString, tClass);
}
public static String getString(Map, ?> map, String key) {
return getString(map, key, null);
}
public static String getString(Map, ?> map, String key, String defaultValue) {
Object currentObj = getObj(map, key, null);
return currentObj == null ? defaultValue : currentObj.toString();
}
public static boolean getBooleanValue(Map, ?> map, String key) {
return getBooleanValue(map, key, false);
}
public static boolean getBooleanValue(Map, ?> map, String key, boolean defaultValue) {
if (map == null) {
return defaultValue;
}
Object o = getObj(map, key, null);
if (o instanceof Boolean) {
return (boolean) o;
}
if (o instanceof String) {
String s = (String) o;
boolean aTrue = "true".equals(s.toLowerCase(Locale.ROOT));
if (aTrue) {
return true;
}
return s.equals(SillyConstant.YesOrNo.YES);
}
return defaultValue;
}
public static T getObj(Map, ?> map, String key) {
return getObj(map, key, null);
}
public static T getObj(Map, ?> map, String key, T defaultValue) {
List names = resolvingFieldName(key);
return getObj(map, names, defaultValue);
}
@SuppressWarnings("all")
public static T getObj(Map, ?> map, List names, T defaultValue) {
if (map == null) {
return defaultValue;
}
if (names.isEmpty()) {
return defaultValue;
}
Object currentObj = map;
for (Serializable name : names) {
if (currentObj == null) {
return defaultValue;
}
if (name instanceof Integer) {
if (currentObj instanceof List) {
List list = (List) currentObj;
Integer i = (Integer) name;
if (list.size() <= i) {
return defaultValue;
}
currentObj = list.get(i);
} else {
return defaultValue;
}
} else if (currentObj instanceof Map) {
Map objMap = (Map) currentObj;
boolean b = objMap.containsKey(name);
if (b) {
currentObj = objMap.get(name);
} else {
return defaultValue;
}
} else if (name instanceof String) {
String fieldName = (String) name;
try {
// 其他类型,通过反射设置值
Class> aClass = currentObj.getClass();
Field declaredField = aClass.getDeclaredField(fieldName);
declaredField.setAccessible(true);
currentObj = declaredField.get(currentObj);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new SillyException("数据类型不支持" + currentObj.getClass() + " 错误:" + e.getMessage(), e);
}
} else {
throw new SillyException("Map值设置数据类型不支持 lastKey:" + name);
}
}
return currentObj == null ? defaultValue : (T) currentObj;
}
/**
* 支持深层命名如: entity.user.loginName / entity[1][office].code
* 解析获取真实属性 (不支持 KEY => null, KEY => "")
* entity.user.loginName => ["entity","user","loginName"]
* entity[1][office].code => ["entity", 1, "office", "code"]
*/
public static List resolvingFieldName(String fieldName) {
List names = new ArrayList<>();
if (fieldName == null) {
return names;
}
String[] fieldNameArr = fieldName.split(FIELD_NAME_SPLIT);
for (String name : fieldNameArr) {
resolvingFieldArrayName(names, name);
}
return names;
}
protected static List resolvingFieldArrayName(List names, String fieldName) {
if (StringUtils.isEmpty(fieldName)) {
return names;
}
if (!fieldName.startsWith("[")) {
int i = fieldName.indexOf("[");
if (i > 0) {
names.add(fieldName.substring(0, i));
} else {
names.add(fieldName);
}
}
if (fieldName.endsWith("]") && fieldName.contains("[")) {
int i = fieldName.indexOf("]");
String substring = fieldName.substring(fieldName.indexOf("[") + 1, i);
if (StringUtils.isNumeric(substring)) {
names.add(Integer.valueOf(substring));
} else {
names.add(substring);
}
return resolvingFieldArrayName(names, fieldName.substring(i + 1));
}
return names;
}
}