Java 在运行时创建用于排序的复合比较器
我的样本请求Java 在运行时创建用于排序的复合比较器,java,json,spring-boot,Java,Json,Spring Boot,我的样本请求 { "requestModel":{ "CUSTID": "100" }, "returnParameters":[ { "name":"NETWORK/NETID", "datatype":"String", "order":"asc", "sequence":1 }, { "name":"INFODATA/NAME", "datatype":"String",
{
"requestModel":{
"CUSTID": "100"
},
"returnParameters":[
{
"name":"NETWORK/NETID",
"datatype":"String",
"order":"asc",
"sequence":1
},
{
"name":"INFODATA/NAME",
"datatype":"String",
"order":"asc",
"sequence":1
},
{
"name":"SOURCE/SYSTEM",
"datatype":"int",
"order":"asc",
"sequence":2
},
]
}
样本响应
Map<String,Object> documentList = new HashMap<String,Object>();
JSONObject jsonObject= new JSONObject(response.getContent());
下面是我动态生成的json响应映射格式[响应参数每次都会根据请求参数而不同]
"responseModel":{
"documents": [
{
"NETWORK":[
{"NETID":"1234"},
{"ACT":"300"}
],
"SOURCE": {
"SYSTEM":"50"
},
"INFODATA":{
"NAME":"PHIL"
}
},
{
"NETWORK":[
{"NETID":"1234"},
{"ACT":"300"}
],
"SOURCE": {
"SYSTEM":"100"
},
"INFODATA":{
"NAME":"PHIL"
}
}
]
}
问题陈述
{
"requestModel":{
"CUSTID": "100"
},
"returnParameters":[
{
"name":"NETWORK/NETID",
"datatype":"String",
"order":"asc",
"sequence":1
},
{
"name":"INFODATA/NAME",
"datatype":"String",
"order":"asc",
"sequence":1
},
{
"name":"SOURCE/SYSTEM",
"datatype":"int",
"order":"asc",
"sequence":2
},
]
}
我需要根据请求中的“returnParameters”进行多级排序,这是动态的。。。
“order”表示升序(或降序),sequence表示排序的优先级,如(sql查询中的group by)
代码
Map<String,Object> documentList = new HashMap<String,Object>();
JSONObject jsonObject= new JSONObject(response.getContent());
有人能帮我在运行时创建复合比较器进行排序吗
注意:-无法创建Java Pojo,因为响应是动态的我的建议:了解:
,允许您通过指定密钥提取程序来构建比较器Comparator.comparating
,它允许您链接多个比较器。只有当前辈说对象相等时,才调用链中后面的比较器Comparator.thanparcing
如果您需要教程:我的建议:了解:
,允许您通过指定密钥提取程序来构建比较器Comparator.comparating
,它允许您链接多个比较器。只有当前辈说对象相等时,才调用链中后面的比较器Comparator.thanparcing
如果需要教程:在注释中的附加问题和说明中的附加信息后编辑
要获得解决方案,您需要执行以下几个步骤:
sequence
的值动态排序。因此,您需要解析那些returnParameters
的名称,并将它们按顺序排列。下面我将它们映射到一个列表中,其中每个字符串[]都有名称
和顺序
(asc/desc)。将使用序列的值对列表进行排序
:
List<String[]> sortParams = params.stream() // params is a List<JSONObject>
.filter(json -> json.containsKey("sequence")) // filter those that have "sequence" attribute
.sorted( sequence ) // sorting using Comparator called sequence
.map(jsonObj -> new String[]{jsonObj.get("name").toString(), jsonObj.get("order").toString()} )
.collect(Collectors.toList());
因此,对于您的示例,排序图看起来像:List(String[]{“NETWORK/NETID”,“asc”},String[]{“INFODATA/NAME”,“asc”},String[]{“SOURCE/SYSTEM”,“asc”})
.get(key)
方法。Simple始终生成对象
。使用此签名编写方法:
public String findSortValue(JSONObject doc, String path){
// split the path
// find the parent
// cast it (parent was returned as an Object of type Object)
// find the child
return value;
}
int individualComparator(String s1, String s2){
int compResult = 0;
try{
int numeric1 = Integer.parseInt(s1);
int numeric2 = Integer.parseInt(s2);
compResult = numeric1 - numeric2; // if this point was reached both values could be parsed
} catch (NumberFormatException nfe){
// if the catch block is reached they weren't numeric
try{
DateTime date1 = DateTime.parse(s1);
DateTime date2 = DateTime.parse(s2);
compResult = date1.compareTo(date2); // compareTo method of joda.time, the library I'm using
} catch (IllegalArgumentException iae){
//if this catch block is reached they weren't dates either
compResult = s1.compareTo(s2);
}
}
return compResult;
})
Comparator<JSONObject> overAllComparator = (jsonObj1, jsonObj2) -> {
List<String[]> sortValuesList = sortParams.stream()
.map(path -> new String[]{ findValueByName(jsonObj1, path), findValueByName(jsonObj2, path) } )
.collect(Collectors.toList());
//assuming we always have 3 attributes to sort on
int comp1 = individualComparator(sortValuesList.get(0)[0], sortValuesList.get(0)[1]);
int comp2 = individualComparator(sortValuesList.get(1)[0], sortValuesList.get(1)[1]);
int comp3 = individualComparator(sortValuesList.get(2)[0], sortValuesList.get(2)[1]);
int result = 0;
if (comp1 != 0){
result = comp1;
} else if (comp2 != 0){
result = comp2;
} else{
result = comp3;
}
return result;
};
Comparator-overAllComparator=(jsonObj1,jsonObj2)->{
列表sortValuesList=sortParams.stream()
.map(路径->新字符串[]{findValueByName(jsonObj1,路径),findValueByName(jsonObj2,路径)})
.collect(Collectors.toList());
//假设我们总是有3个属性进行排序
int comp1=单个比较器(sortValuesList.get(0)[0],sortValuesList.get(0)[1]);
int comp2=单个比较器(sortValuesList.get(1)[0],sortValuesList.get(1)[1]);
int comp3=单个比较器(sortValuesList.get(2)[0],sortValuesList.get(2)[1]);
int结果=0;
如果(comp1!=0){
结果=comp1;
}否则如果(comp2!=0){
结果=comp2;
}否则{
结果=comp3;
}
返回结果;
};
jsonObj1
,位置1的值为jsonObj2
,并将其收集在sortValuesList
中。然后,对于每个要排序的属性,它得到individualComparator的结果de>method。然后它沿着这一行,作为整体比较的结果返回第一个没有结果为0的值(当比较器结果为0时,两个值相等)
现在唯一缺少的是请求中的asc/desc值。您可以通过链接int comp1=individualComparator(sortValuesList.get(0)[0],sortValuesList.get(0)[1]);
来添加它,如果字符串等于“desc”,则使用一个简单的方法获取int&a字符串并将int乘以-1。(请记住,在sortparms
中,我们在数组的位置1添加了order
的值)
由于我们创建的第一个列表,sortparms
是根据请求中指示的优先级排序的,并且我们总是按照此列表的顺序执行所有操作,因此结果是按此顺序进行多重排序。它是通用的,将由请求中的returnParams
的内容动态确定。您可以将其应用于您r使用在注释中的附加问题和说明中的附加信息后编辑的Collections.sort()
列出JSONObject
要获得解决方案,您需要执行以下几个步骤:
您希望根据请求中属性序列的值动态排序。因此,您需要解析那些returnParameters
的名称并将它们按顺序排列。下面我将它们映射到一个列表,其中每个字符串[]都有名称
和顺序
(asc/desc)。列表将使用序列的值进行排序
:
List<String[]> sortParams = params.stream() // params is a List<JSONObject>
.filter(json -> json.containsKey("sequence")) // filter those that have "sequence" attribute
.sorted( sequence ) // sorting using Comparator called sequence
.map(jsonObj -> new String[]{jsonObj.get("name").toString(), jsonObj.get("order").toString()} )
.collect(Collectors.toList());
因此,对于您的示例,排序图看起来像:List(String[]{“NETWORK/NETID”,“asc”},St
class ReturnParameterComparator implements Comparator<JSONObject> {
private List<ReturnParameter> params; //set via constructor
public int compare( JSONObject left, JSONObject right) {
int result = 0;
for( ReturnParameter p : params ) {
//how exactly you get those values depends on the actual structure of your data and parameters
String leftValueStr = left.get( p );
String rightValueStr = right.get( p );
switch( p.datatype ) {
case "String":
result = String.compare( leftValueStr, rightValueStr );
break;
case "int":
//convert and then compare - I'll leave the rest for you
}
//invert the result if the order is descending
if( "desc".equals(p.order ) {
result += -1;
}
//the values are not equal so return the order, otherwise continue with the next parameter
if( result != 0 ) {
return result;
}
}
//at this point all values are to be considered equal, otherwise we'd have returned already (from the loop body)
return 0;
}
}