数据类型自动转换的解决方案
java8、jdk8
背景
为方便测试框架数据处理以及方便查看一些数据,弄了一个工具类,部分要点简要说明。
主要涉及到字符串与其他类型的相互转换,无其他类型之间的相互转换。
问题分析
字符串转换为对象的方法(未完待续)
int
或Integer
:判定int.class.equals(typeClass) || Integer.class.equals(typeClass)
后,使用Integer.parseInt(str)
方法;boolean
或Boolean
:判定boolean.class.equals(typeClass) || Boolean.class.equals(typeClass)
后,使用Boolean.parseBoolean(toString(o))
方法;String
:判定String.class.equals(typeClass)
后,使用o.toString()
方法;List
:判定List.class.isAssignableFrom(typeClass)
后,去除前后缀,逗号分割后,将每个元素按照元素类型(参数传入)分别转换;- 元素类型:
(Class<?>) ((ParameterizedType) typeClass.getGenericSuperclass()).getActualTypeArguments()[0]
- 元素类型:
Array
:判定typeClass.isArray()
后,利用List方法获得元素数组,然后根据元素类型,再次封装为相应对象:- 元素类型:
typeClass.getComponentType()
; int
:手动创建int数组(int[]) Array.newInstance(int.class, list.size())
,依次填入各元素;Integer
:使用List对象list.toArray(new Integer[0])
方法创建;String
:使用List对象list.toArray(new String[0])
方法创建;
- 元素类型:
对象转换为字符串的方法(未完待续)
Class
对象:判定Class.class.equals(o.getClass())
后,使用((Class<?>) o).getName()
,
数组类型使用cls.getComponentType().getName() + "[]""
表示- 基本类型数组或对象数组:判断
o.getClass().isArray()
后,使用o.getClass().getComponentType()
获取元素类型,将对象强转为对应 类型数组,- 对于封装对象类型,使用
Arrays.stream(//强转的数组//).map(Convert::toString).collect(Collectors.joining(","))
- 对于基本类型数组,使用
String.join(",", Arrays.stream(//强转的数组//).mapToObj(Convert::toString).toArray(String[]::new))
- 对于封装对象类型,使用
注:int[]、String[]、Object[]等都可以处理,流处理中使用的Convert::toString方法,就是我对象转换为字符串方法的重载,能递归处理数组内各元素
List
对象:判断o instanceof List
后,使用((List<?>) o).toArray()
转换为数组,然后使用上文处理数组的方法处理- 其他数据类型(基本数据类型):复杂数据类型条件筛选完后,基本数据类型使用
String.valueOf(o)
处理成字符串
解决方案
工具类源码大概如下(未完待续):
java
/**
* 主要负责字符串型数据和各种类型对象的转换
* <p>
* 主要包括如下几类功能
* 1. 字符串转成各类型对象的各方法
* 2. 各类型对象转换成字符串的方法
* 3. 按指定类型转换数据成相应对象的方法
* 4. 按指定各种类型的列表,依次转换数据列表中的各数据,组装成相应对象列表的方法
*/
public class Convert {
/**
* 按指定各元素类型的列表,依次转换数据列表中的各数据,组装成相应对象列表
*
* @param typesClass 类型的Class列表
* @param params 数据字符串列表
* @return 对象列表
* @throws Exception 类型列表和数据列表为空或长度不一致时,抛出异常中止运行
*/
public static Object[] toInstances(Class<?>[] typesClass, String[] params) throws Exception {
if (null == typesClass || null == params) {
throw new Exception("实参列表或形参类型列表为空!");
} else if (typesClass.length != params.length) {
throw new Exception("实参列表(" + params.length + ")参数类型列表(" + typesClass.length + ")长度不一致!");
}
Object[] ans = new Object[typesClass.length];
for (int i = 0; i < typesClass.length; i++) {
ans[i] = toInstance(typesClass[i], params[i]);
}
return ans;
}
/**
* 将数据字符串根据指定类型转换成相应对象
*
* @param typeClass 对象的Class类型
* @param param 数据字符串
* @return 类型匹配失败时返回null
*/
public static Object toInstance(Class<?> typeClass, String param) {
Object ans = null;
if (int.class.equals(typeClass) || Integer.class.equals(typeClass)) {
ans = toInteger(param);
} else if (boolean.class.equals(typeClass) || Boolean.class.equals(typeClass)) {
ans = toBoolean(param);
} else if (String.class.equals(typeClass)) {
ans = toString(param);
} else if (typeClass.isArray()) {
ans = toArray(typeClass.getComponentType(), param);
} else if (List.class.isAssignableFrom(typeClass)) {
Class<?> actualTypeArgument = (Class<?>) ((ParameterizedType) typeClass.getGenericSuperclass()).getActualTypeArguments()[0];
ans = toList(actualTypeArgument, param);
}
return ans;
}
/**
* 按不同数组类型,将入参对象转换为数组对象
*
* @param elementType 数组元素类型
* @param o 要转换为数组的对象
* @return 数组类型未匹配成功时,返回 new Object[]{}
*/
public static Object toArray(Class<?> elementType, Object o) {
return toArray(elementType, o, null);
}
/**
* 按不同数组类型,将入参对象转换为数组对象
*
* @param elementType 数组元素类型
* @param o 要转换为数组的对象
* @param surrounds 前后缀
* @return 数组类型未匹配成功时,返回 new Object[]{}
*/
public static Object toArray(Class<?> elementType, Object o, String[] surrounds) {
return toArray(elementType, o, surrounds, null);
}
/**
* 按不同数组类型,将入参对象转换为数组对象
*
* @param elementType 数组元素类型
* @param o 要转换为数组的对象
* @param surrounds 前后缀
* @param delimiter 分隔符
* @return 数组类型未匹配成功时,返回 new Object[]{}
*/
public static Object toArray(Class<?> elementType, Object o, String[] surrounds, String delimiter) {
List<?> list = toList(elementType, o, surrounds, delimiter);// 如果直接将List转成数组,泛型信息会丢失,这里需要二次处理
if (int.class.equals(elementType)) {
return toIntArray(list); // 基本数据类型数组需要单独处理
} else if (Integer.class.equals(elementType)) {
return list.toArray(new Integer[0]);
} else if (String.class.equals(elementType)) {
return list.toArray(new String[0]);
}
return new Object[]{};
}
/**
* 将List列表转换为int数组
*
* @param list
* @return
*/
public static int[] toIntArray(List<?> list) {
int[] ansArray = (int[]) Array.newInstance(int.class, list.size());
for (int i = 0; i < list.size(); i++) {
ansArray[i] = toInteger(list.get(i));
}
return ansArray;
}
/**
* 将对象转换为List列表
*
* @param elementType 指定元素类型
* @param o 要转为列表的对象
* @return List列表(ArrayList对象)
*/
public static List<?> toList(Class<?> elementType, Object o) {
return toList(elementType, o, null, null);
}
/**
* 将对象转换为List列表
*
* @param elementType 指定元素类型
* @param o 要转为列表的对象
* @param surrounds 前后缀,默认使用 new String[]{"[", "]"}
* @param delimiter 分隔符,默认使用 ","(无空格)
* @return List列表(ArrayList对象)
*/
public static List<?> toList(Class<?> elementType, Object o, String[] surrounds, String delimiter) {
List<Object> ansObjectList = new ArrayList<>();
if (null == o) {
return ansObjectList;
}
if (null == delimiter) {
delimiter = ","; // 分隔符默认不带空格
}
if (null == surrounds || surrounds.length < 2) {
surrounds = new String[]{"[", "]"};
}
String dataString = toString(o);
if (0 == dataString.indexOf(surrounds[0])) { // 剔除前缀
dataString = dataString.substring(surrounds[0].length());
}
if (dataString.length() - surrounds[1].length() == dataString.indexOf(surrounds[1])) { // 剔除后缀(列表内元素及分隔符不包含后缀的情况下,否则有bug)
dataString = dataString.substring(0, dataString.length() - surrounds[1].length());
}
String[] dataStrings = dataString.split(delimiter);
for (String dataStr : dataStrings) {
ansObjectList.add(toInstance(elementType, dataStr));
}
return ansObjectList;
}
/**
* 检查对象类型,分门别类对对象作相应处理
*
* @param o 要获取字符串的对象
* @return 未能识别类型的对象,返回String.valueOf(o)值
*/
public static String toString(Object o) {
return toString(o, null);
}
/**
* 检查对象类型,分门别类对对象作相应处理
*
* @param o 要获取字符串的对象
* @param surrounds 列表、数组类型要加注的前后缀
* @return 未能识别类型的对象,返回String.valueOf(o)值
*/
public static String toString(Object o, String[] surrounds) {
return toString(o, surrounds, null);
}
/**
* 检查对象类型,分门别类对对象作相应处理
*
* @param o 要获取字符串的对象
* @param surrounds 列表、数组类型要加注的前后缀
* @param joinDelimiter 列表、数组类型元素间的分隔符
* @return 未能识别类型的对象,返回String.valueOf(o)值
*/
public static String toString(Object o, String[] surrounds, String joinDelimiter) {
if (null == o) {
return "";
}
if (Class.class.equals(o.getClass())) {
Class<?> oClass = (Class<?>) o;
return oClass.isArray() ? oClass.getComponentType().getName() + "[]" : oClass.getName(); // 数组类型使用元素类型加方括号表示
} else if (String.class.equals(o.getClass())) {
return o.toString();
} else if (o.getClass().isArray()) {
return toArrayString(o, surrounds, joinDelimiter);
} else if (o instanceof List) {
return toString(((List<?>) o).toArray(), surrounds, joinDelimiter); // List对象转为Object数组
}
return String.valueOf(o);
}
/**
* 将数组转换为字符串
* <p>
* (由于数组类型不能直接转换,所以)根据元素类型,对不同数组作相应转换处理
*
* @param o 数组对象
* @param surrounds 前后缀,默认使用方括号 new String[]{"[", "]"}
* @param joinDelimiter 分隔符,默认使用", "
* @return 未能识别的元素类型返回其String.valueOf(o) + "-ArrStr"值
*/
public static String toArrayString(Object o, String[] surrounds, String joinDelimiter) {
// 分隔符和前后缀字符统一处理,各类型子方法不再校验,故设为私有
if (null == o) {
return "";
}
if (null == joinDelimiter) {
joinDelimiter = ", ";
}
if (null == surrounds || surrounds.length < 2) {
surrounds = new String[]{"[", "]"};
}
// 各类型数组分别(数组类型不同无法直接向父类强转)强制类型转换,调用Stream方式处理
if (Class.class.equals(o.getClass().getComponentType())) {
return toObjectArrayString(Arrays.stream((Class[]) o), surrounds, joinDelimiter);
} else if (Integer.class.equals(o.getClass().getComponentType())) {
return toObjectArrayString(Arrays.stream((Integer[]) o), surrounds, joinDelimiter);
} else if (String.class.equals(o.getClass().getComponentType())) {
return toObjectArrayString(Arrays.stream((String[]) o), surrounds, joinDelimiter);
} else if (Object.class.equals(o.getClass().getComponentType())) {
return toObjectArrayString(Arrays.stream((Object[]) o), surrounds, joinDelimiter);
} else if (int.class.equals(o.getClass().getComponentType())) {
return toIntArrayString(((int[]) o), surrounds, joinDelimiter);
}
return String.valueOf(o) + "-ArrStr";
}
/**
* 将int数组转换为字符串
*
* @param array int数组
* @param surrounds 前后缀(括号)
* @param joinDelimiter 分隔符(逗号)
* @return
*/
private static String toIntArrayString(int[] array, String[] surrounds, String joinDelimiter) {
return surrounds[0] + String.join(joinDelimiter, Arrays.stream(array).mapToObj(Convert::toString).toArray(String[]::new)) + surrounds[1];
}
/**
* 将stream流中的元素组装为字符串
*
* @param stream 包装类型数组的流序列
* @param surrounds 前后缀(括号)
* @param joinDelimiter 分隔符(逗号)
* @return
*/
private static String toObjectArrayString(Stream<?> stream, String[] surrounds, String joinDelimiter) {
return surrounds[0] + stream.map(Convert::toString).collect(Collectors.joining(joinDelimiter)) + surrounds[1];
}
/**
* 转换为布尔值
*
* @param o
* @return null时返回false
*/
public static Boolean toBoolean(Object o) {
if (null == o) {
return false;
}
return Boolean.parseBoolean(toString(o));
}
/**
* 转换为整数
*
* @param o
* @return o的整数值,null时返回0
*/
public static Integer toInteger(Object o) {
if (null == o) {
return 0;
}
return Integer.parseInt(toString(o));
}
}
声明:本文使用八爪鱼rpa工具从gitee自动搬运本人原创(或摘录,会备注出处)博客,如版式错乱请评论私信,如情况紧急或久未回复请致邮 xkm.0jiejie0@qq.com 并备注原委;引用本人笔记的链接正常情况下均可访问,如打不开请查看该链接末尾的笔记标题(右击链接文本,点击 复制链接地址,在文本编辑工具粘贴查看,也可在搜索框粘贴后直接编辑然后搜索),在本人博客手动搜索该标题即可;如遇任何问题,或有更佳方案,欢迎与我沟通!