rutime中没有POJOS并没有为多级排序构建Build Composite比较器

时间:2019-05-12 04:05:00

标签: java

已经发布的问题没有适用于我的解决方案,因为所有其他使用POJO字段进行排序的解决方案都没有,但是案例不是POJO,因为请求/响应都是动态json,因此     我需要执行多级[具有多个属性]排序。     多个属性的排序是根据输入请求动态进行的。

 Have created individual Comparator for each dataTypes like String,Numeric, etc

例如IntegerComparator

public class IntegerComparator implements <DTOObject> {
 @Override
public int compare(DTOObject o1, DTOObject o2){
    return o1.getAccountID()-o2.getAccountID();
 }
} //since my json response is dynamic. getter method is framed 
    dynamically based on input request tells which parameter to sort.

StringComparator:-

public class StringComparator implements <DTOObject> {
 @Override
public int compare(DTOObject o1, DTOObject o2){
    return o1.getActName()-o2.getActName();
 }
} // since my json response is dynamic. getter method is framed
     dynamically based on input request tells which parameter to sort.

主类:-

 public class AccountService {
 public SearchResponse accountFetch(){
  //To do
  List <JSONObject> resultList= someObject.fetchAcoount("12345678");
  // the resultList is dynamic JSON reponse,
   so no setter/getter method cannot be created
  Collections.sort(resultList, new IntegerComparatorimplements ());
  // how to invoke multi level sorting here as sorting attributes are 
     dynamic and upto N parameters
 }
 }

问题

由于我的json响应是动态的,因此在每个比较器中,基于输入请求(“ responseParameters”)动态构造getter方法,以告知哪个参数 排序。

现在如何在运行时构建复合比较器以进行多级排序?如何调用所有比较器进行多级排序?

下面的示例请求中的

“ responseParameters”告诉您要排序的参数,要排序的参数序列[多级排序],用于json响应的参数的数据类型等。

样品申请:-

{
  {
  "RequestOject":{
    "CUSTID": "100"
  },
 "responseParameters":[
    {
    "name":"NAME",
    "datatype":"String",
    "order":"asc",
    "sequence":1
    },
    {
    "name":"SYSTEM",
    "datatype":"int",
    "order":"asc",
    "sequence":2
    },
    {
    "name":"AGE",
    "datatype":"int",
    "order":"desc",
    "sequence":4
    },
    {
    "name":"TITLE",
    "datatype":"String",
    "order":"desc",
    "sequence":3
    },
upto... N parameters
    ]
 }
}

注意:排序属性是动态的,最多1个... N个参数

样品响应:-

 "ResponseObject":{
   "documents": [
     {
    "DETAIL":[
       {"CUSTID":"789"},
       {"ACCT":"SAV"},
       {"AGE":"22"}
      ],
    "SRC": {
      "SYSTEM":"IB",
      "TITLE":"PEM"
      },
   "SYSDATA":{
     "NAME":"MATT"
     }
     },
         {
    "DETAIL":[
       {"CUSTID":"522"},
       {"ACCT":"CUR"},
       {"AGE":"40"}
      ],
     "SRC": {
      "SYSTEM":"IB",
      "TITLE":"CON"
      },
   "SYSDATA":{
     "NAME":"JAMES"
     }
  }
 ]
}

1 个答案:

答案 0 :(得分:0)

我想不出一种简单的方法来做到这一点。您必须创建Comparator并将要排序的属性的json传递给它,然后创建执行此操作的动态代码。另外,假设您只有字段名作为字符串,则必须使用反射来获取字段的值。

我写了一个例子,请注意:

  1. 我不知道您使用的是哪个Json lib,我在示例中使用了GSON
  2. 有一些使用反射的方法,我使用了较短的反射,但是请参考Reflection generic get field value以获取您的首选方法。如果您知道值的范围并希望避免反射,则也可以使用切换大小写
  3. 我留下了2个待办事项
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

import java.lang.reflect.Field;
import java.util.Comparator;

public class MyComprator implements Comparator<DTOObject> {

    private JsonArray params;

    public MyComprator(JsonArray params) {
        this.params = params;
        // TODO: Here possible to sort params by 'sequence' if needed
    }

    @Override
    public int compare(DTOObject o1, DTOObject o2) {
        for (int i = 0; i < params.size(); i++) {
            JsonObject param = params.get(i).getAsJsonObject();
            String fieldName = param.get("name").getAsString();
            String datatype = param.get("datatype").getAsString();
            int order = param.get("order").getAsString().equals("asc") ? 1 : -1;

            int compare = 0;

            if (datatype.equals("String")) {
                 compare = getField(o1, fieldName, String.class).compareTo(
                               getField(o2, fieldName, String.class));
            }
            else if (datatype.equals("int")) {
                compare = getField(o1, fieldName, Integer.class).compareTo(
                          getField(o2, fieldName, Integer.class));
            }

            if (compare != 0) {
                return compare * order;
            }
        }

        return 0;
    }

    private <T> T getField(DTOObject obj, String fieldName, Class<T> type) {
        try {
            // Use refelction
            Field field = DTOObject.class.getDeclaredField(fieldName);
            field.setAccessible(true);
            Object value = field.get(obj);
            return (T) value;
        }
        catch (NoSuchFieldException | IllegalAccessException e) {
            // TODO: Handle exception
            return null;
        }
    }
}