com.arsframework.util.Objects Maven / Gradle / Ivy
package com.arsframework.util;
import java.io.*;
import java.net.URL;
import java.net.URLDecoder;
import java.net.JarURLConnection;
import java.nio.channels.Channel;
import java.time.ZoneId;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.Temporal;
import java.util.*;
import java.util.function.Function;
import java.util.jar.JarFile;
import java.util.jar.JarEntry;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.lang.reflect.*;
import java.lang.annotation.Annotation;
import com.arsframework.annotation.Min;
import com.arsframework.annotation.Nonnull;
/**
* 对象处理工具类
*
* @author yongqiang.wu
*/
public abstract class Objects {
/**
* 空字段数组
*/
public static final Field[] EMPTY_FIELD_ARRAY = new Field[0];
/**
* 空类对象数组
*/
public static final Class>[] EMPTY_CLASS_ARRAY = new Class>[0];
/**
* 对象迭代器接口
*/
public interface Iterator {
/**
* 对象迭代
*
* @param object 当前对象
* @param index 当前迭代下标
*/
void iteration(Object object, int index);
}
/**
* 遍历对象(字典、数据、可迭代)
*
* @param object 遍历目标对象
* @param iterator 对象遍历迭代器
*/
public static void foreach(Object object, @Nonnull Iterator iterator) {
if (isEmpty(object)) {
return;
}
int i = 0; // 迭代下标
if (object instanceof Map) {
for (Map.Entry, ?> o : ((Map, ?>) object).entrySet()) {
iterator.iteration(o, i++);
}
} else if (object instanceof Iterable) {
for (Object o : (Iterable>) object) {
iterator.iteration(o, i++);
}
} else if (object instanceof int[]) {
for (int o : (int[]) object) {
iterator.iteration(o, i++);
}
} else if (object instanceof short[]) {
for (short o : (short[]) object) {
iterator.iteration(o, i++);
}
} else if (object instanceof float[]) {
for (float o : (float[]) object) {
iterator.iteration(o, i++);
}
} else if (object instanceof long[]) {
for (long o : (long[]) object) {
iterator.iteration(o, i++);
}
} else if (object instanceof double[]) {
for (double o : (double[]) object) {
iterator.iteration(o, i++);
}
} else if (object instanceof char[]) {
for (char o : (char[]) object) {
iterator.iteration(o, i++);
}
} else if (object instanceof byte[]) {
for (byte o : (byte[]) object) {
iterator.iteration(o, i++);
}
} else if (object instanceof boolean[]) {
for (boolean o : (boolean[]) object) {
iterator.iteration(o, i++);
}
} else if (object instanceof Object[]) {
for (Object o : (Object[]) object) {
iterator.iteration(o, i++);
}
} else {
iterator.iteration(object, i++);
}
}
/**
* 字段访问接口
*/
public interface Accessor {
/**
* 字段访问
*
* @param field 字段对象
* @param index 访问序数
*/
void access(Field field, int index);
}
/**
* 字段访问中断接口
*/
public interface AccessBreaker {
/**
* 判断是否已中断访问
*
* @param field 字段对象
* @param index 访问序数
* @return true/false
*/
boolean isBroken(Field field, int index);
}
/**
* 类及父类实例字段访问
*
* @param clazz 对象类型
* @param accessor 访问接口
*/
public static void access(Class> clazz, Accessor accessor) {
access(clazz, accessor, null);
}
/**
* 类及父类实例字段访问
*
* @param clazz 对象类型
* @param accessor 访问接口
* @param breaker 访问中断接口
*/
public static void access(@Nonnull Class> clazz, @Nonnull Accessor accessor, AccessBreaker breaker) {
int index = 0;
boolean broken = false;
do {
for (Field field : clazz.getDeclaredFields()) {
if (breaker != null && (broken = breaker.isBroken(field, index))) {
break;
}
if (!Modifier.isStatic(field.getModifiers()) && !field.getName().startsWith("this$")) {
accessor.access(field, index++);
}
}
} while (!broken && (clazz = clazz.getSuperclass()) != Object.class);
}
/**
* 获取对象类型
*
* @param objects 对象数组
* @return 类型数组
*/
@Nonnull
public static Class>[] getTypes(Object... objects) {
Class>[] types = new Class>[objects.length];
for (int i = 0; i < objects.length; i++) {
Object object = objects[i];
types[i] = object == null ? null : object.getClass();
}
return types;
}
/**
* 判断类型是否是基本数据类型
*
* @param clazz 数据类型
* @return true/false
*/
public static boolean isBasicClass(Class> clazz) {
try {
return clazz == null ? false : ((Class>) clazz.getField("TYPE").get(null)).isPrimitive();
} catch (NoSuchFieldException | IllegalAccessException e) {
return clazz.isPrimitive() || clazz == Byte.class || clazz == Character.class || clazz == Integer.class || clazz == Short.class
|| clazz == Long.class || clazz == Float.class || clazz == Double.class || clazz == Boolean.class;
}
}
/**
* 判断对象类型是否是元对象类型
*
* @param clazz 对象类型
* @return true/false
*/
public static boolean isMetaClass(Class> clazz) {
return clazz != null && (clazz == Object.class || clazz == Class.class || clazz.isEnum() || clazz.isArray() || clazz.isInterface()
|| isBasicClass(clazz) || Number.class.isAssignableFrom(clazz) || Modifier.isAbstract(clazz.getModifiers())
|| CharSequence.class.isAssignableFrom(clazz) || Number.class.isAssignableFrom(clazz) || Date.class.isAssignableFrom(clazz)
|| Temporal.class.isAssignableFrom(clazz) || Map.class.isAssignableFrom(clazz) || Collection.class.isAssignableFrom(clazz)
|| Function.class.isAssignableFrom(clazz) || Annotation.class.isAssignableFrom(clazz) || File.class.isAssignableFrom(clazz)
|| Channel.class.isAssignableFrom(clazz) || InputStream.class.isAssignableFrom(clazz)
|| OutputStream.class.isAssignableFrom(clazz) || Reader.class.isAssignableFrom(clazz) || Writer.class.isAssignableFrom(clazz));
}
/**
* 判断数据类型是否是数字类型
*
* @param clazz 数据类型
* @return true/false
*/
public static boolean isNumberClass(Class> clazz) {
return clazz != null && (Number.class.isAssignableFrom(clazz) || clazz == byte.class || clazz == char.class
|| clazz == short.class || clazz == int.class || clazz == double.class || clazz == long.class);
}
/**
* 判断对象是否为数字
*
* @param object 对象
* @return true/false
*/
public static boolean isNumber(Object object) {
return object != null && isNumberClass(object.getClass());
}
/**
* 判断对象是否为空
*
* @param object 对象
* @return true/false
*/
public static boolean isEmpty(Object object) {
return object == null
|| (object instanceof byte[] && ((byte[]) object).length == 0)
|| (object instanceof char[] && ((char[]) object).length == 0)
|| (object instanceof int[] && ((int[]) object).length == 0)
|| (object instanceof short[] && ((short[]) object).length == 0)
|| (object instanceof long[] && ((long[]) object).length == 0)
|| (object instanceof float[] && ((float[]) object).length == 0)
|| (object instanceof double[] && ((double[]) object).length == 0)
|| (object instanceof boolean[] && ((boolean[]) object).length == 0)
|| (object instanceof Object[] && ((Object[]) object).length == 0)
|| (object instanceof CharSequence && ((CharSequence) object).length() == 0)
|| (object instanceof Map && ((Map, ?>) object).isEmpty())
|| (object instanceof Collection && ((Collection>) object).isEmpty());
}
/**
* 根据字段名称获取字段对象
*
* @param clazz 类对象
* @param name 字段名称
* @return 字段对象
*/
@Nonnull
public static Field getField(Class> clazz, String name) {
do {
try {
return clazz.getDeclaredField(name);
} catch (NoSuchFieldException e) {
}
} while ((clazz = clazz.getSuperclass()) != Object.class);
throw new RuntimeException(String.format("No such field '%s'", name));
}
/**
* 获取对象所有实例字段
*
* @param clazz 对象类型
* @return 字段对象数组
*/
@Nonnull
public static Field[] getFields(Class> clazz) {
List fields = new LinkedList<>();
access(clazz, (field, i) -> fields.add(field));
return fields.toArray(EMPTY_FIELD_ARRAY);
}
/**
* 获取对象所有实例属性名称
*
* @param clazz 对象类型
* @return 字段名称数组
*/
@Nonnull
public static String[] getProperties(Class> clazz) {
List properties = new LinkedList<>();
access(clazz, (field, i) -> properties.add(field.getName()));
return properties.toArray(Strings.EMPTY_ARRAY);
}
/**
* 获取字段值
*
* @param object 对象实例
* @param field 字段对象
* @return 值对象
*/
@Nonnull
public static Object getValue(Object object, Field field) {
if (!field.isAccessible()) {
field.setAccessible(true);
}
try {
return field.get(object);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
/**
* 获取对象指定字段的值
*
* @param object 对象实例
* @param property 属性名称
* @return 字段值
*/
@Nonnull
public static Object getValue(Object object, String property) {
int division = property.indexOf('.'); // 属性分割符下标
if (division <= 0) {
return getValue(object, getField(object.getClass(), property));
}
Object value = getValue(object, getField(object.getClass(), property.substring(0, division)));
return value == null ? null : getValue(value, property.substring(division + 1));
}
/**
* 获取对象实例属性值
*
* @param object 对象实例
* @return 键/值对象
*/
@Nonnull
public static Map getValues(Object object) {
Map values = new LinkedHashMap<>();
access(object.getClass(), (field, i) -> values.put(field.getName(), getValue(object, field)));
return values;
}
/**
* 设置对象指定属性的值
*
* @param object 对象实例
* @param field 字段对象
* @param value 字段值
*/
public static void setValue(@Nonnull Object object, @Nonnull Field field, Object value) {
if (!field.isAccessible()) {
field.setAccessible(true);
}
try {
field.set(object, toObject(field.getType(), value));
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
/**
* 设置对象指定属性的值,对象属性必须支持set方法
*
* @param object 对象实例
* @param property 属性名称
* @param value 字段值
*/
public static void setValue(@Nonnull Object object, @Nonnull String property, Object value) {
setValue(object, getField(object.getClass(), property), value);
}
/**
* 将Map对象所包含的键/值填充到Bean对象实例对应的非静态属性中
*
* @param object 对象实例
* @param values 需要填充的属性/值Map对象
*/
@Nonnull
public static void setValues(Object object, Map values) {
if (!values.isEmpty()) {
access(object.getClass(), (field, i) -> {
if (values.containsKey(field.getName())) {
setValue(object, field, values.get(field.getName()));
}
});
}
}
/**
* 将属性值填充到Bean对象实例对应的非静态属性中
*
* @param object 对象实例
* @param values 需要填充的属性值数组
*/
public static void setValues(Object object, Object... values) {
if (values.length > 0) {
access(object.getClass(), (field, i) -> setValue(object, field, values[i]), (field, i) -> i >= values.length);
}
}
/**
* 对象拷贝(属性复制)
*
* @param 数据类型
* @param source 源对象
* @return 目标对象
*/
@Nonnull
public static T copy(T source) {
T target = (T) initialize(source.getClass());
copy(source, target);
return target;
}
/**
* 拷贝对象实例,深度克隆
*
* @param 数据类型
* @param source 源对象
* @return 对象实例副本
*/
@Nonnull
public static T clone(T source) {
try {
return (T) Streams.deserialize(Streams.serialize(source));
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
/**
* 对象拷贝(属性复制)
*
* @param 数据类型
* @param source 源对象
* @param target 目标对象
*/
@Nonnull
public static void copy(T source, T target) {
access(source.getClass(), (field, i) -> setValue(target, field, getValue(source, field)));
}
/**
* 初始化对象实例
*
* @param 数据类型
* @param type 对象类型
* @return 对象实例
*/
@Nonnull
public static T initialize(Class type) {
try {
return type.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
/**
* 初始化对象实例
*
* @param 数据类型
* @param type 对象类型
* @param values 属性值数组
* @return 对象实例
*/
public static T initialize(Class type, Object... values) {
T instance = initialize(type);
setValues(instance, values);
return instance;
}
/**
* 初始化对象实例
*
* @param 数据类型
* @param type 对象类型
* @param values 初始化参数
* @return 对象实例
*/
public static T initialize(Class type, Map values) {
T instance = initialize(type);
setValues(instance, values);
return instance;
}
/**
* 根据泛型参数类型获取泛型类型
*
* @param parameterizedType 泛型参数类型
* @return 泛型类型数组
*/
@Nonnull
private static Class>[] getGenericTypes(ParameterizedType parameterizedType) {
Type[] types = parameterizedType.getActualTypeArguments();
List> classes = new ArrayList<>(types.length);
for (Type type : types) {
if (type instanceof Class) {
classes.add((Class>) type);
}
}
return classes.toArray(EMPTY_CLASS_ARRAY);
}
/**
* 获取类对象的泛型
*
* @param clazz 类对象对象
* @return 泛型类型数组
*/
@Nonnull
public static Class>[] getGenericTypes(Class> clazz) {
Type type = clazz.getGenericSuperclass();
if (type instanceof ParameterizedType) {
return getGenericTypes((ParameterizedType) type);
}
Class> parent = clazz.getSuperclass();
return parent == null ? EMPTY_CLASS_ARRAY : getGenericTypes(parent);
}
/**
* 获取字段的泛型
*
* @param field 字段对象
* @return 泛型类型数组
*/
@Nonnull
public static Class>[] getGenericTypes(Field field) {
Type type = field.getGenericType();
return type instanceof ParameterizedType ? getGenericTypes((ParameterizedType) type) : EMPTY_CLASS_ARRAY;
}
/**
* 获取基本数据包装类型
*
* @param clazz 基本数据类型
* @return 基本数据包装类型
*/
@Nonnull
public static Class> getBasicWrapClass(Class> clazz) {
if (clazz == byte.class || clazz == Byte.class) {
return Byte.class;
} else if (clazz == char.class || clazz == Character.class) {
return Character.class;
} else if (clazz == int.class || clazz == Integer.class) {
return Integer.class;
} else if (clazz == short.class || clazz == Short.class) {
return Short.class;
} else if (clazz == long.class || clazz == Long.class) {
return Long.class;
} else if (clazz == float.class || clazz == Float.class) {
return Float.class;
} else if (clazz == double.class || clazz == Double.class) {
return Double.class;
} else if (clazz == boolean.class || clazz == Boolean.class) {
return Boolean.class;
}
throw new IllegalArgumentException("Invalid basic type: " + clazz);
}
/**
* 构建对象类型空数组
*
* @param type 对象类型
* @param 数据类型
* @return 数组对象
*/
public static T[] buildEmptyArray(Class type) {
return buildArray(type, 0);
}
/**
* 构建对象类型数组
*
* @param type 对象类型
* @param length 数组长度
* @param 数据类型
* @return 数组对象
*/
@Nonnull
public static T[] buildArray(Class type, @Min(0) int length) {
return (T[]) Array.newInstance(isBasicClass(type) ? getBasicWrapClass(type) : type, length);
}
/**
* 从包package中获取所有的Class
*
* @param pack 包路径名
* @return Java类集合
*/
@Nonnull
public static List> getClasses(String pack) {
List> classes = new ArrayList<>();
// 获取包的名字 并进行替换
String path = pack.replace('.', '/');
// 定义一个枚举的集合 并进行循环来处理这个目录下的things
try {
Enumeration dirs = Thread.currentThread().getContextClassLoader().getResources(path);
// 循环迭代下去
while (dirs.hasMoreElements()) {
// 获取下一个元素
URL url = dirs.nextElement();
// 得到协议的名称
String protocol = url.getProtocol();
// 如果是以文件的形式保存在服务器上
if ("file".equals(protocol)) {
// 以文件的方式扫描整个包下的文件 并添加到集合中
classes.addAll(getClasses(pack, URLDecoder.decode(url.getFile(), Strings.CHARSET_UTF8)));
} else if ("jar".equals(protocol)) {
// 获取jar
JarFile jar = ((JarURLConnection) url.openConnection()).getJarFile();
// 从此jar包 得到一个枚举类
Enumeration entries = jar.entries();
// 同样的进行循环迭代
while (entries.hasMoreElements()) {
// 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件
JarEntry entry = entries.nextElement();
String name = entry.getName();
// 如果是以/开头的
if (name.charAt(0) == '/') {
// 获取后面的字符串
name = name.substring(1);
}
// 如果前半部分和定义的包名相同
if (name.startsWith(path)) {
int idx = name.lastIndexOf('/');
// 如果以"/"结尾 是一个包
if (idx != -1) {
// 获取包名 把"/"替换成"."
pack = name.substring(0, idx).replace('/', '.');
}
// 如果可以迭代下去 并且是一个包,且是一个.class文件 而且不是目录
if (idx != -1 && name.endsWith(".class") && !entry.isDirectory()) {
// 去掉后面的".class" 获取真正的类名
String className = name.substring(pack.length() + 1, name.length() - 6);
classes.add(Class.forName(pack + '.' + className));
}
}
}
}
}
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
return classes;
}
/**
* 以文件的形式来获取包下的所有Class
*
* @param pack 包名
* @param path 包路径
* @return 对象列表
*/
@Nonnull
private static List> getClasses(String pack, String path) {
File dir = new File(path);
if (!dir.exists() || !dir.isDirectory()) {
return new ArrayList<>(0);
}
List> classes = new ArrayList<>();
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
for (File file : dir.listFiles((file) -> file.isDirectory() || file.getName().endsWith(".class"))) {
if (file.isDirectory()) {
classes.addAll(getClasses(pack + '.' + file.getName(), file.getAbsolutePath()));
} else {
// 如果是java类文件 去掉后面的.class 只留下类名
String className = file.getName().substring(0, file.getName().length() - 6);
try {
classes.add(classLoader.loadClass(pack + '.' + className));
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
return classes;
}
/**
* 获取目标异常信息
*
* @param throwable 异常对象
* @return 信息内容
*/
@Nonnull
public static String getThrowableMessage(Throwable throwable) {
Throwable cause;
while ((cause = throwable.getCause()) != null) {
throwable = cause;
}
return throwable.getMessage();
}
/**
* 对象类型转换
*
* @param 对象类型
* @param type 转换目标类型
* @param object 被转换对象
* @return 转换后对象
*/
public static T toObject(@Nonnull Class type, Object object) {
if (object == null || type == Object.class || type.isAssignableFrom(object.getClass())) {
return (T) object;
} else if (type == byte.class || type == Byte.class) {
return (T) toByte(object);
} else if (type == char.class || type == Character.class) {
return (T) toCharacter(object);
} else if (type == boolean.class || type == Boolean.class) {
return (T) toBoolean(object);
} else if (type == int.class || type == Integer.class) {
return (T) toInteger(object);
} else if (type == BigInteger.class) {
return (T) (object instanceof BigInteger ? object : new BigInteger(object.toString()));
} else if (type == BigDecimal.class) {
return (T) (object instanceof BigDecimal ? object : new BigDecimal(object.toString()));
} else if (type == short.class || type == Short.class) {
return (T) toShort(object);
} else if (type == float.class || type == Float.class) {
return (T) toFloat(object);
} else if (type == double.class || type == Double.class) {
return (T) toDouble(object);
} else if (type == long.class || type == Long.class) {
return (T) toLong(object);
} else if (Enum.class.isAssignableFrom(type)) {
return (T) toEnum((Class) type, object);
} else if (Date.class.isAssignableFrom(type)) {
return (T) toDate(object);
} else if (LocalDate.class.isAssignableFrom(type)) {
return (T) (object instanceof LocalDate ? object : object instanceof LocalDateTime ? ((LocalDateTime) object).toLocalDate() :
Dates.adapter(toDate(object)).toLocalDate());
} else if (LocalDateTime.class.isAssignableFrom(type)) {
return (T) (object instanceof LocalDateTime ? object : object instanceof LocalDate ?
((LocalDate) object).atStartOfDay(ZoneId.systemDefault()).toLocalDateTime() : Dates.adapter(toDate(object)));
} else if (type == String.class) {
return (T) Strings.toString(object);
} else if (type == Class.class) {
return (T) toClass(object);
}
throw new IllegalArgumentException("Cannot convert " + object + " to " + type);
}
/**
* 字节类型转换
*
* @param object 被转换对象
* @return 字节对象
*/
public static Byte toByte(Object object) {
return object == null ? null : object instanceof Byte ? (Byte) object :
object instanceof Number ? ((Number) object).byteValue() : Byte.parseByte(object.toString());
}
/**
* 字符类型转换
*
* @param object 被转换对象
* @return 字符对象
*/
public static Character toCharacter(Object object) {
return object == null ? null : object instanceof Character ? (Character) object :
Character.valueOf((char) (object instanceof Number ? ((Number) object).intValue() : Integer.parseInt(object.toString())));
}
/**
* 真假类型转换
*
* @param object 被转换对象
* @return 真假对象
*/
public static Boolean toBoolean(Object object) {
return object == null ? null : object instanceof Boolean ? (Boolean) object : object instanceof Number ?
((Number) object).intValue() > 0 ? Boolean.TRUE : Boolean.FALSE : Boolean.parseBoolean(object.toString());
}
/**
* 整形类型转换
*
* @param object 被转换对象
* @return 整形对象
*/
public static Integer toInteger(Object object) {
return object == null ? null : object instanceof Integer ? (Integer) object :
object instanceof Number ? ((Number) object).intValue() : Integer.parseInt(object.toString());
}
/**
* 短整形类型转换
*
* @param object 被转换对象
* @return 短整形对象
*/
public static Short toShort(Object object) {
return object == null ? null : object instanceof Short ? (Short) object :
object instanceof Number ? ((Number) object).shortValue() : Short.parseShort(object.toString());
}
/**
* 单精度浮点类型转换
*
* @param object 被转换对象
* @return 单精度浮点对象
*/
public static Float toFloat(Object object) {
return object == null ? null : object instanceof Float ? (Float) object :
object instanceof Number ? ((Number) object).floatValue() : Float.parseFloat(object.toString());
}
/**
* 双精度浮点类型转换
*
* @param object 被转换对象
* @return 双精度浮点对象
*/
public static Double toDouble(Object object) {
return object == null ? null : object instanceof Double ? (Double) object :
object instanceof Number ? ((Number) object).doubleValue() : Double.parseDouble(object.toString());
}
/**
* 长整形类型转换
*
* @param object 被转换对象
* @return 长整形对象
*/
public static Long toLong(Object object) {
return object == null ? null : object instanceof Long ? (Long) object :
object instanceof Number ? ((Number) object).longValue() : Long.parseLong(object.toString());
}
/**
* 枚举类型转换
*
* @param 数据类型
* @param type Enum类型
* @param object 被转换对象
* @return 枚举实例
*/
public static > T toEnum(@Nonnull Class type, Object object) {
if (object == null || object.getClass() == type) {
return (T) object;
} else if (object instanceof Number) {
int ordinal = ((Number) object).intValue();
try {
Method method = type.getDeclaredMethod("values");
method.setAccessible(true);
for (T value : (T[]) method.invoke(type)) {
if (value.ordinal() == ordinal) {
return value;
}
}
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
throw new IllegalArgumentException("No enum of " + type.getCanonicalName() + " with ordinal " + ordinal);
}
return Enum.valueOf(type, object.toString());
}
/**
* 日期类型转换
*
* @param object 被转换对象
* @return 日期
*/
public static Date toDate(Object object) {
return toDate(object, Dates.ALL_DATE_FORMATS);
}
/**
* 日期类型转换
*
* @param object 被转换对象
* @param patterns 格式模式数组
* @return 日期
*/
public static Date toDate(Object object, String... patterns) {
return object == null ? null : object instanceof Date ? (Date) object : object instanceof LocalDate ?
Dates.adapter((LocalDate) object) : object instanceof LocalDateTime ? Dates.adapter((LocalDateTime) object) :
object instanceof Number ? new Date(((Number) object).longValue()) : Dates.parse(object.toString(), patterns);
}
/**
* 类对象转换
*
* @param object 被转换对象
* @return 类对象
*/
public static Class> toClass(Object object) {
try {
return object == null ? null : object instanceof Class ? (Class>) object : Class.forName(object.toString());
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
/**
* 计算对象数组的hash值
*
* @param objects 对象数组
* @return hash值
*/
public static int hash(Object... objects) {
return java.util.Objects.hash(objects);
}
/**
* 判断两个对象是否相同
*
* @param object 对象
* @param other 对象
* @return true/false
*/
public static boolean equal(Object object, Object other) {
return object != null && other != null && object.getClass() == other.getClass() && object.equals(other);
}
/**
* 获取两个对象实例不同属性值
*
* @param 数据类型
* @param object 对象实例
* @param other 对象实例
* @return 不同属性值
*/
@Nonnull
public static Map difference(T object, T other) {
Map difference = new LinkedHashMap<>();
access(object.getClass(), (field, i) -> {
Object value1 = getValue(object, field);
Object value2 = getValue(other, field);
if (!equal(value1, value2)) {
difference.put(field.getName(), new Object[]{value1, value2});
}
});
return difference;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy