数据类型自动转换的解决方案

java8、jdk8

背景

为方便测试框架数据处理以及方便查看一些数据,弄了一个工具类,部分要点简要说明。

主要涉及到字符串与其他类型的相互转换,无其他类型之间的相互转换。

轻量测试框架实现与使用的总篇可见此文

问题分析

字符串转换为对象的方法(未完待续)

  • intInteger:判定int.class.equals(typeClass) || Integer.class.equals(typeClass)后,使用Integer.parseInt(str)方法;
  • booleanBoolean:判定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)处理成字符串

解决方案

工具类源码大概如下(未完待续):

/**
 * 主要负责字符串型数据和各种类型对象的转换
 * <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 并备注原委;引用本人笔记的链接正常情况下均可访问,如打不开请查看该链接末尾的笔记标题(右击链接文本,点击 复制链接地址,在文本编辑工具粘贴查看,也可在搜索框粘贴后直接编辑然后搜索),在本人博客手动搜索该标题即可;如遇任何问题,或有更佳方案,欢迎与我沟通!

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部