首页 > 其他分享 >数据类型自动转换的解决方案

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

时间:2024-09-20 14:23:11浏览次数:12  
标签:return String surrounds 解决方案 Object 数据类型 param 数组 转换

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

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自动搬运本人原创(或摘录,会备注出处)博客,如版式错乱请评论私信,如情况紧急或久未回复请致邮 [email protected] 并备注原委;引用本人笔记的链接正常情况下均可访问,如打不开请查看该链接末尾的笔记标题(右击链接文本,点击 复制链接地址,在文本编辑工具粘贴查看,也可在搜索框粘贴后直接编辑然后搜索),在本人博客手动搜索该标题即可;如遇任何问题,或有更佳方案,欢迎与我沟通!

标签:return,String,surrounds,解决方案,Object,数据类型,param,数组,转换
From: https://blog.csdn.net/qq_41623592/article/details/142318053

相关文章

  • 农田灌溉水质监测物联网解决方案
    在农业生产中,确保灌溉水质的优良是非常重要的。优质的灌溉水可以为农作物提供必要的水分和养分,促进其健康生长。这就需要对灌溉水源进行定期检测,评估其是否适合用于农田灌溉,并根据检测结果采取相应的措施来改善水质或选择其他水源。 《农田灌溉水质标准》(GB5084-2021)要求;对经人为......
  • 井下变电所智能巡检解决方案
    1      背景.51.1背景综述.51.2参考资料.51.3建设原则.62      建设目标与总体架构.73      变电所移动巡控子系统.93.1主要功能.93.1.1自检功能.93.1.2声光报警.93.1.3自主避障.93.1.4语音对讲.93.1.5停送电系统联动.93.1.6......
  • 兼收并蓄 TypeScript - 基础: 数据类型
    源码https://github.com/webabcd/TypeScriptDemo作者webabcd兼收并蓄TypeScript-基础:数据类型示例如下:basic\dataType.ts{//基本数据类型boolean,number,string,symbolleta:boolean=true;letb:number=10;letc:string="abc";......
  • 【Java DTO、VO类型转换工具类,对象与对象之间赋值】全部一行代码搞定!爽
    对象转换工具一、modelmapper介绍二、安装(一)引入依赖(二)添加工具类三、使用示例(一)单个对象转换(一)简单转换(二)转换时对转换后的对象处理(二)转换时对转换后的对象、源对象处理(一)批量转换(一)简单转换(二)转换时对转换后的对象处理(二)转换时对转换后的对象、源对象处理一、m......
  • 医疗系统医院如何选择静态转换开关
    医院作为一个重要的公共场所,对供电的连续性和稳定性要求非常高。在医院中,有许多敏感负荷,如MR、CT、各类分析仪、麻醉机、手术监护仪等。当出现电压波动或供电故障时,将严重影响医疗设备的安全运行,严重时会造成人员伤亡。为了保障供电的连续性,可以通过双电源冗余配置的方式,提高敏感负......
  • GSS静态转换开关(STS)在电厂的抗晃电应用
    电厂作为典型的连续型生产企业,是一个自动化程度很高的特殊行业,自动化的生产设备依赖于供电系统的安全、稳定、连续运行。大容量机组发电机的DCS控制系统,包括各种热工自动装置,如自动调节用组装仪表、汽轮机电液数字调节装置、锅炉联锁及安全监察系统FSSS、汽机监视仪表(TSI)、协调控制......
  • 静态转换开关(STS)在储能项目中的应用价值
    储能技术的发展历史可以追溯到相当早的时期,但近年来,由于环境保护、能源安全、技术进步和政策支持等多重因素的影响,储能领域得到了更多的关注和发展,尤其是储能车的出现。储能车的问世有助于符合当今社会发展需求,推动交通领域的能源转型和减排目标的实现。同时,储能技术在车辆领域中不......
  • 代码随想录 -- 二叉树 -- 把二叉搜索树转换为累加树
    538.把二叉搜索树转换为累加树-力扣(LeetCode)思路:定义pre变量用来记录当前节点的前一个节点(右中左顺序遍历)的值。递归出口:当root为空时,return。单层递归逻辑:(右中左)右:self.tra(root.right)中:令root的值为它本身加上pre,更新pre为当前root的值;左:self.tra(root.left)class......
  • 代码随想录 -- 二叉树 -- 将有序数组转换为二叉搜索树
    108.将有序数组转换为二叉搜索树-力扣(LeetCode)思路:(注意题目要求是平衡二叉树!!!)递归出口:当传入数组为空时,返回空。单层递归逻辑:找到数组中间的值,令其为root,数组左边为root的左子树,数组右边为root的右子树。最后返回root。classSolution(object):defsortedArrayTo......
  • C语言类型与强制类型转换
    目录类型关键字sizeof如何理解强制类型转化不同类型的0null字符设备(补充)char有有符号和无符号两种类型,字符是无符号类型.(补充)getchar的返回值为什么是int键盘输入的内容,以及往显示器中打印的内容,都是字符-->键盘/显示器称为字符设备类型C语言为何有类型?让我们能够......