Android自定义json数组转化成list方法

想写一个小软件,引入其他人的json工具类动不动就几百kb,太大了,比我自己的软件都大,所以自定义一个json工具类

罗嗦版本,带注释,真的一路坎坷写下来的,本来以为他没有这样的方法没想到他有。。。。

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class JSONObjectUtil {

    /**
     * 将一个json转化成一个对象
     * @param jsonStr json字符串
     * @param targetClass 需要转化的类型
     * @param <T> 类型的class类
     * @return 返回的是T的实例化对象
     */
    public static <T> T parse2Object(String jsonStr, Class<T> targetClass) {
        try {
            JSONObject jsonObject = new JSONObject(jsonStr);
            Field[] targetClassFields = targetClass.getDeclaredFields();
            Class c = Class.forName(targetClass.getName());
            //将泛型类new出来
            final T resultObject = (T) c.newInstance();

            for (Field targetClassField : targetClassFields) {
                //判断当前字段类型
                Class<?> currentFieldType = targetClassField.getType();
                //获取目标类中的所有方法,调用目标类中的所有set方法注入字段
                Method[] targetClassMethods = targetClass.getDeclaredMethods();

                //去json里面get("targetClassField"),然后去targetClass里面set+“targetClassField”
                String targetClassFieldName = targetClassField.getName();

                //现在里面就是具体的参数了, param好像是入参,value好像是出参用的
                //Object jsonValue = jsonObject.get(targetClassFieldName);//如果直接getId获取到的是Integer,但是setId的时候需要Long类型
                //所以这一行代码写在forEach里面,get+“bean里面的传入类型”


                //??????为什么这里也获取出来的是他原本的类型???那他为什么要设置这么多getLong,getDouble来迷惑我?????,那我写这么多岂不是浪费了????????
                //System.out.println("获取的数据类型-->"+jsonValue.getClass().getName());


                //调用的方法是targetClass里面set+“targetClassField”
                System.out.println("\n\n\n\n");
                Arrays.stream(targetClassMethods)
                        .filter(targetClassMethod -> targetClassMethod.getName().equals("set" + toUpperFirstOne(targetClassField.getName())))
                        .forEach(targetClassMethod -> {
                            try {


                                //jsonObject.get(targetClassFieldName);把这个方法替换成下面的jsonObjectGetMethod这个,因为当主键Id是1、2、3时,JSONObject默认帮我们生成的是Integer,但是我们需要的是Long
                                //这个方法就是JSONObject中的getLong/getString/getDouble
                                Method jsonObjectGetMethod = Arrays.stream(jsonObject.getClass().getDeclaredMethods())
                                        .filter(jsonObjectMethod -> {
                                            //获取到的是java.lang.String
                                            Class<?> parameterType = targetClassMethod.getParameterTypes()[0];
                                            String methodName="get" + parameterType.getName()
                                                    .substring(parameterType.getName().lastIndexOf(".") + 1);
                                            if (methodName.contains("Int"))
                                                methodName="getInt";
                                            return jsonObjectMethod.getName().equals(methodName);
                                        }).collect(Collectors.toList()).get(0);//里面一定只有一个方法,因为这是过滤bean的方法,bean里面不可能出现重载方法
                                Object jsonValue = jsonObjectGetMethod.invoke(jsonObject, targetClassFieldName);
                                //System.out.println("jsonValue类型-->"+jsonValue.getClass().getName());
                                targetClassMethod.invoke(resultObject, jsonValue);
                                //System.out.println("当前对象-->" + resultObject);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        });
   /*             IntStream.range(0, targetClassDeclaredMethods.length)
                        .filter(i -> targetClassDeclaredMethods[i].getName().contains("set"))//剩下所有的set方法
                        .forEach(i -> {
                            String currentFieldAllTypeName=currentFieldType.getName();
                            //获取类型名字,类似于String、Integer这样的,上面的获取出来是java.lang.String这样的
                            String currentFieldTypeName = currentFieldAllTypeName.substring(currentFieldAllTypeName.lastIndexOf(".") + 1);
                            try {
                                Method[] jsonObjectMethod = jsonObject.getClass().getDeclaredMethods();
                                //里面全是jsonObject中的带有get的方法,好像没啥用,到下面invoke的时候好像还是会变成object
                                Method jsonObjectGetMethod = Arrays.stream(jsonObjectMethod)
                                        .filter(jsonObjectMethodEle -> jsonObjectMethodEle.getName().equals("get"+currentFieldTypeName))//get加类型名字就是要执行的方法
                                        .collect(Collectors.toList()).get(0);//里面只可能有一个方法,那就是"get"+currentFieldTypeName,但是不这样写返回的是个数组
                                //System.out.println("需要执行的方法-->"+jsonObjectGetMethod.getName());
                                //jsonObject中执行get方法,返回的参数是String或者Long之类的
                                Object jsonObjectGetResultParam = jsonObjectGetMethod.invoke(jsonObject, declaredField.getName());

                                *//**
                 * 我真的好无语,我以为反射return的类型肯定是Object,结果不是Objetc,是本该有的类型,是Long就是Long只是显示成Object,好气,这么多白写了,估计转化类型的过程是在这里完成的《.filter(jsonObjectMethodEle -> jsonObjectMethodEle.getName().equals("get"+currentFieldTypeName))》
                 //调用currentFieldTypeName的valueOf方法
                 //获取typeClass 他是String.class,或者是Integer.class,或者是Long.class
                 Class<?> typeClass=Class.forName(currentFieldAllTypeName);
                 //获取类中的所有方法
                 Method[] typeClassAllMethods = typeClass.getDeclaredMethods();
                 Method typeClassValueOfMethod = Arrays.stream(typeClassAllMethods)
                         .filter(typeClassAllMethod -> typeClassAllMethod.getName().equals("valueOf"))
                         .collect(Collectors.toList()).get(5);//这个时候里面有一堆valueOf的重载方法



                 //System.out.println("valueOF--->"+typeClassValueOfMethod.getName());
                 //Object o = jsonObject.get(declaredField.getName());//调用方法时传的参数
                 //调用的是String/Long/Integer的valueOf方法
                 //调用完成以后,哪怕是返回的是Object,但是调用getClass().getName()还是String/Integer,本质上就已经是String/Integer/Long了
                 //将json里面的参数转化成他应该是的类型,字符串转化成字符串,long转化成long
                 Object jsonParamConvertTypeClass = typeClassValueOfMethod.invoke(null, jsonObjectGetResultParam);
                 //System.out.println("Object类型本质---->"+jsonParamConvertTypeClass.getClass().getName());
                 //java反射的返回值一直是Object,很苦恼,自己写一个方法
                 *//*

                                System.out.println("当前方法-->"+targetClassDeclaredMethods[i]);
                                System.out.println("传入参数-->"+jsonObjectGetResultParam);
                                System.out.println("参数类型-->"+jsonObjectGetResultParam.getClass().getName());
                                System.out.println("对象实例-->"+resultObject);
                                 //调用目标类中的所有set方法注入参数
                                targetClassDeclaredMethods[i].invoke(resultObject,jsonObjectGetResultParam);

                                System.out.println("没报错");
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        });//调用所有的set方法setjson里面的值
                //System.out.println("declaredField-->" + declaredField.getName());
           */
            }
            return resultObject;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 首字母转大写
     *
     * @param s
     * @return
     */
    public static String toUpperFirstOne(String s) {
        if (Character.isUpperCase(s.charAt(0))) {
            return s;
        } else {
            return (new StringBuilder())
                    .append(Character.toUpperCase(s.charAt(0)))
                    .append(s.substring(1))
                    .toString();
        }
    }


    /**
     * 将一个json数组转化成List对象
     * @param jsonStr json数组的字符串
     * @param targetClass 要转化list的类型
     * @param <T> list泛型类型
     * @return list的对象
     */
    public static <T> List<T> parse2Objects(String jsonStr, Class<T> targetClass) {

        List<T> resultList=new ArrayList<>();
        try {
            JSONArray jsonArray = new JSONArray(jsonStr);
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jsonObject = new JSONObject(jsonArray.getString(i));
                T t = JSONObjectUtil.parse2Object(jsonObject.toString(), targetClass);
                resultList.add(t);
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }

        return resultList;
    }

}

正常开发使用只带基本注释版本,其实删删注释也没多少


import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class JSONObjectUtil {

    /**
     * 将一个json转化成一个对象
     * @param jsonStr json字符串
     * @param targetClass 需要转化的类型
     * @param <T> 类型的class类
     * @return 返回的是T的实例化对象
     */
    public static <T> T parse2Object(String jsonStr, Class<T> targetClass) {
        try {
            JSONObject jsonObject = new JSONObject(jsonStr);
            Field[] targetClassFields = targetClass.getDeclaredFields();
            Class c = Class.forName(targetClass.getName());
            //将泛型类new出来
            final T resultObject = (T) c.newInstance();

            for (Field targetClassField : targetClassFields) {
                //判断当前字段类型
                Class<?> currentFieldType = targetClassField.getType();
                //获取目标类中的所有方法,调用目标类中的所有set方法注入字段
                Method[] targetClassMethods = targetClass.getDeclaredMethods();

                //去json里面get("targetClassField"),然后去targetClass里面set+“targetClassField”
                String targetClassFieldName = targetClassField.getName();

                //现在里面就是具体的参数了, param好像是入参,value好像是出参用的
                //Object jsonValue = jsonObject.get(targetClassFieldName);//如果直接getId获取到的是Integer,但是setId的时候需要Long类型
                //所以这一行代码写在forEach里面,get+“bean里面的传入类型”

                //调用的方法是targetClass里面set+“targetClassField”
                System.out.println("\n\n\n\n");
                Arrays.stream(targetClassMethods)
                        .filter(targetClassMethod -> targetClassMethod.getName().equals("set" + toUpperFirstOne(targetClassField.getName())))
                        .forEach(targetClassMethod -> {
                            try {
                                //jsonObject.get(targetClassFieldName);把这个方法替换成下面的jsonObjectGetMethod这个,因为当主键Id是1、2、3时,JSONObject默认帮我们生成的是Integer,但是我们需要的是Long
                                //这个方法就是JSONObject中的getLong/getString/getDouble
                                Method jsonObjectGetMethod = Arrays.stream(jsonObject.getClass().getDeclaredMethods())
                                        .filter(jsonObjectMethod -> {
                                            //获取到的是java.lang.String
                                            Class<?> parameterType = targetClassMethod.getParameterTypes()[0];
                                            String methodName="get" + parameterType.getName()
                                                    .substring(parameterType.getName().lastIndexOf(".") + 1);
                                            if (methodName.contains("Int"))
                                                methodName="getInt";
                                            return jsonObjectMethod.getName().equals(methodName);
                                        }).collect(Collectors.toList()).get(0);//里面一定只有一个方法,因为这是过滤bean的方法,bean里面不可能出现重载方法
                                Object jsonValue = jsonObjectGetMethod.invoke(jsonObject, targetClassFieldName);
                                targetClassMethod.invoke(resultObject, jsonValue);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        });
            }
            return resultObject;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 首字母转大写
     *
     * @param s
     * @return
     */
    public static String toUpperFirstOne(String s) {
        if (Character.isUpperCase(s.charAt(0))) {
            return s;
        } else {
            return (new StringBuilder())
                    .append(Character.toUpperCase(s.charAt(0)))
                    .append(s.substring(1))
                    .toString();
        }
    }


    /**
     * 将一个json数组转化成List对象
     * @param jsonStr json数组的字符串
     * @param targetClass 要转化list的类型
     * @param <T> list泛型类型
     * @return list的对象
     */
    public static <T> List<T> parse2Objects(String jsonStr, Class<T> targetClass) {

        List<T> resultList=new ArrayList<>();
        try {
            JSONArray jsonArray = new JSONArray(jsonStr);
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jsonObject = new JSONObject(jsonArray.getString(i));
                T t = JSONObjectUtil.parse2Object(jsonObject.toString(), targetClass);
                resultList.add(t);
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }

        return resultList;
    }

}

2022 08 13

   @RequiresApi(api = Build.VERSION_CODES.N)
    public static <T> List<T> jsonToList(String jsonStr, Class<T> targetClass){
        List<T> targetList=new ArrayList<>();
        try {
            JSONArray jsonArray=new JSONArray(jsonStr);
            //遍历jsonArray
            for(int i=0;i<jsonArray.length();i++){
                String jsonElement = jsonArray.get(i).toString();
                //System.out.println("jsonElement="+jsonElement);
                JSONObject jsonObject=new JSONObject(jsonElement);
                //获取Account的所有field,调用jsonObject的get+Field方法
                Field[] targetClassAllField = targetClass.getDeclaredFields();
                //将泛型类new出来
                T targetClassObject= targetClass.newInstance();
                for (Field field : targetClassAllField) {
                    String fieldStr=field.getName();
                    //调用jsonObject指定get(field)的方法
                    Object jsonEle=jsonObject.get(fieldStr);
                    //调用targetClassObject指定set+field的方法
                    System.out.println("jsonEle="+jsonEle);
                    if(!Objects.isNull(jsonEle.toString())&&!jsonEle.toString().equals("null")){
                        //获取set方法
                        Method targetMethod=getTargetMethod(fieldStr,targetClassObject.getClass());
                        System.out.println("获取到的反法="+targetMethod);
                        targetMethod.invoke(targetClassObject,jsonEle);
                    }
                }
                System.out.println("targetClassObject="+targetClassObject);
                targetList.add(targetClassObject);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return targetList;
    }

    private static Method getTargetMethod(String filterStr,Class<?> aClass) {
        for (Method targetClassMethod : aClass.getDeclaredMethods()) {
            String name = targetClassMethod.getName();
            if(name.contains(convertInitialUpper(filterStr))&&name.contains("set")){
                //System.out.println("返回方法="+targetClassMethod);
                return targetClassMethod;
            }
        }
        return null;
    }
    public static String convertInitialUpper(String word) {
        // 方式二:效率高
        char[] chars = word.toCharArray();
        // 首字母转大写(ASCII编码前移)
        chars[0] -= 32;
        return new String(chars);
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值