【发布时间】:2021-07-25 15:08:19
【问题描述】:
我有这个 json,我希望能够按不同类型的多个字段值对其进行排序,同时保留之前的排序顺序。
{
"code": "1603",
"description": "",
"score": 10,
"max": 100,
"effts": "2021-12-07T00:00:00",
"expDate": "2021-06-21",
"charityMaxCount": 1400000,
"charityUseCount": 938297,
"title": "",
"imageUrl": "",
"status": "INACTIVE"
},
{
"code": "1604",
"description": "",
"score": 10,
"max": 100,
"effts": "2020-12-07T00:00:00",
"expDate": "2021-06-21",
"charityMaxCount": 1400000,
"charityUseCount": 938297,
"title": "",
"imageUrl": "",
"status": "INACTIVE"
},
{
"code": "1600",
"description": "",
"score": 10,
"max": 100,
"effts": "2021-12-07T00:00:00",
"expDate": "2021-06-21",
"charityMaxCount": 1400000,
"charityUseCount": 938297,
"title": "",
"imageUrl": "",
"status": "ACTIVE"
},
{
"code": "1606",
"description": "",
"score": 10,
"max": 100,
"effts": "2022-12-07T00:00:00",
"expDate": "2021-06-21",
"charityMaxCount": 1400000,
"charityUseCount": 938297,
"title": "",
"imageUrl": "",
"status": "ACTIVE"
},
{
"code": "1601",
"description": "",
"score": 10,
"max": 100,
"effts": "2020-12-07T00:00:00",
"expDate": "2021-06-21",
"charityMaxCount": 1400000,
"charityUseCount": 938297,
"title": "",
"imageUrl": "",
"status": "ACTIVE"
}
]
我应该决定对其进行排序的字段是通过另一个 json 给出的:
{
"id": 1,
"field": "status",
"type": "string",
"sortMode": "ASC"
},
{
"id": 2,
"field": "expDate",
"type": "string",
"sortMode": "ASC"
}
]
我设法通过将 json 数组转换为 Hashmap<String,Object> 的列表来实现这一点
并编写了一个自定义比较器。问题是当我按 ASC 顺序按 status 排序时,将 ACTIVE 条目放在顶部,我不希望这个顺序弄乱例如,当我选择按 expDate 等其他字段对其进行排序时。
这是我的代码:
public String sort() throws JsonProcessingException {
List<TreeMap<String, String>> sortOrder = readSortOrder(sortOrderJson);
List<HashMap<String, Object>> payLoad = readPayLoad(payloadJson);
ObjectMapper objectMapper = new ObjectMapper();
if (sortOrder.size() > 1) {
for (TreeMap<String, String> map : sortOrder) {
if (map.get(Constants.SORT_MODE).equals(SortOrder.DSC.toString())) {
payLoad.sort(new MapComparator(map.get(Constants.FIELD)).reversed());
} else {
payLoad.sort(new MapComparator(map.get(Constants.FIELD)));
}
}
}
return objectMapper.writeValueAsString(payLoad);
}
public List<HashMap<String, Object>> readPayLoad(String jsonInput) {
ObjectMapper mapper = new ObjectMapper();
List<HashMap<String, Object>> jsonList = new ArrayList<>();
try {
HashMap[] payLoadDTOS = mapper.readValue(jsonInput, HashMap[].class);
jsonList = Arrays.asList(payLoadDTOS);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return jsonList;
}
public List<TreeMap<String, String>> readSortOrder(String sortOrder) {
final ObjectMapper objectMapper = new ObjectMapper();
List<TreeMap<String, String>> jsonList = new ArrayList<>();
try {
TreeMap[] sortOrderDTOS = objectMapper.readValue(sortOrder, TreeMap[].class);
jsonList = Arrays.asList(sortOrderDTOS);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return jsonList;
}
这是比较器:
public class MapComparator implements Comparator<Map<String, Object>> {
private final String key;
public MapComparator(String key) {
this.key = key;
}
@Override
public int compare(Map<String, Object> one, Map<String, Object> two) {
Object first = one.get(key);
Object second = two.get(key);
if (first instanceof String && second instanceof String) {
if ((isValidDate((String) first) && isValidDate((String) second))
|| (isValidDateTime((String) first) && isValidDateTime((String) second))) {
return DateTimeComparator.getInstance().compare(first, second);
} else {
return ((String) first).compareTo((String) second);
}
} else if (first instanceof Integer && second instanceof Integer) {
return ((Integer) first).compareTo((Integer) second);
}
return 0;
}
}
我认为我应该将 ACTIVE 和 INACTIVE 分别放在另外两个集合中并分别排序,但是我可以进行分离的字段可能是动态的,并且可能每次改变。我该如何通过算法处理这个问题?
【问题讨论】:
-
@gkhaos 我认为我的比较器中的这些检查就像您编写了多个比较器并且认为这两个问题在不同的上下文中一样