根据键对 java 个对象进行排序
Sort java object based on a key
我有一个数据列表,我需要按以下方式对 pre_release
下的 job_status
进行有效排序,仅适用于具有 run
的对象:1
"FAILED", "WARNING", "SUCCESS"
我正在尝试使用冒泡排序,但需要帮助
//compareData contains list of object which needs to be sorted
List<HashMap<String, Object>> compareData = new ArrayList<HashMap<String, Object>>();
HashMap<String, Object> tempObj = new HashMap<String, Object>();
for (int i=0; i<compareData.size(); i++) {
for (int j=1; i<(compareData.size() - 1); j++) {
if (Integer.parseInt(compareData.get(j-1).get(JOB_STATUS_CODE).toString()) > Integer.parseInt(compareData.get(j).get(JOB_STATUS_CODE).toString())) {
tempObj = compareData.get(j-1);
//compareData.get(j-1) = compareData.get(j);
}
}
}
比较数据
[{
"pre_release": [{
"message": "The environment GYAN-WIN2008-64-SP2-DC-1 used by this connection is inactive.",
"start_time": "2015-05-27T22:45:25.000-07:00",
"run": "1",
"job_status": "FAILED",
"job_status_code": "3"
}, {
"message": "The environment GYAN-WIN2008-64-SP2-DC-1 used by this connection is inactive.",
"start_time": "2015-05-27T22:00:25.000-07:00",
"run": "2",
"job_status": "FAILED",
"job_status_code": "3"
}, {
"message": "The environment GYAN-WIN2008-64-SP2-DC-1 used by this connection is inactive.",
"start_time": "2015-05-27T21:15:25.000-07:00",
"run": "3",
"job_status": "FAILED",
"job_status_code": "3"
}],
"task_name": "DB to DB xxx.yyy.42.62_2",
"task_id": "000ABC0G000000000007",
"production": {
"message": "The environment Redhat Linux used by this connection is inactive.",
"start_time": "2015-05-21T05:50:05.000-07:00",
"job_status": "FAILED",
"job_status_code": "3"
}
} {
"pre_release": [{
"message": "The environment Redhat Linux used by this connection is inactive.",
"start_time": "2015-05-21T05:50:05.000-07:00",
"run": "1",
"job_status": "FAILED",
"job_status_code": "3"
}, {
"message": "The environment Redhat Linux used by this connection is inactive.",
"start_time": "2015-05-21T05:45:05.000-07:00",
"run": "2",
"job_status": "FAILED",
"job_status_code": "3"
}, {
"message": "The environment Redhat Linux used by this connection is inactive.",
"start_time": "2015-05-21T05:40:05.000-07:00",
"run": "3",
"job_status": "FAILED",
"job_status_code": "3"
}],
"task_name": "IPS_WS_Test",
"task_id": "000ABC0K000000000096",
"production": {
"message": null,
"start_time": "2015-02-02T13:05:00.000-08:00",
"job_status": "SUCCESS",
"job_status_code": "1"
}
}, {
"pre_release": [{
"message": null,
"start_time": "2015-02-02T13:05:00.000-08:00",
"run": "1",
"job_status": "SUCCESS",
"job_status_code": "1"
}, {
"message": null,
"start_time": "2015-02-02T13:00:00.000-08:00",
"run": "2",
"job_status": "SUCCESS",
"job_status_code": "1"
}, {
"message": null,
"start_time": "2015-02-02T12:55:00.000-08:00",
"run": "3",
"job_status": "SUCCESS",
"job_status_code": "1"
}],
"task_name": "Logan josh mct win",
"task_id": "000ABC0Z00000000009V",
"production": {
"message": "No errors encountered.",
"start_time": "2015-05-19T13:31:28.000-07:00",
"job_status": "SUCCESS",
"job_status_code": "1"
}
}, {
"pre_release": [{
"message": null,
"start_time": "2015-05-14T07:27:10.000-07:00",
"run": "1",
"job_status": "WARNINGS",
"job_status_code": "2"
}, {
"message": "Target field [MD_COntact__c] does not exist in the object [onlytesting__c].",
"start_time": "2015-05-14T07:25:25.000-07:00",
"run": "2",
"job_status": "FAILED",
"job_status_code": "3"
}, {
"message": "Target field [MD_COntact__c] does not exist in the object [onlytesting__c].",
"start_time": "2015-05-14T07:24:55.000-07:00",
"run": "3",
"job_status": "FAILED",
"job_status_code": "3"
}],
"task_name": "Lambba",
"task_id": "000ABCI0000000002XP",
"production": {
"message": null,
"start_time": "2015-05-14T07:27:10.000-07:00",
"job_status": "WARNINGS",
"job_status_code": "2"
}
}, {
"pre_release": [{
"message": "No errors encountered.",
"start_time": "2015-05-19T13:31:28.000-07:00",
"run": "1",
"job_status": "SUCCESS",
"job_status_code": "1"
}, {
"message": "No errors encountered.",
"start_time": "2015-05-19T13:12:15.000-07:00",
"run": "2",
"job_status": "SUCCESS",
"job_status_code": "1"
}, {
"message": "No errors encountered.",
"start_time": "2015-05-19T12:51:50.000-07:00",
"run": "3",
"job_status": "SUCCESS",
"job_status_code": "1"
}],
"task_name": "chahamedidata_baja2",
"task_id": "000ABC0I000000000301",
"production": {
"message": "[ERROR] com.baja.api.bajaServiceQueryOperationTimeIntervalFaultFaultFaultMessage: Query is limited to 1 request every 250 milliseconds (there have been 64.2 milliseconds since the last request)",
"start_time": "2015-05-19T13:20:05.000-07:00",
"job_status": "SUCCESS",
"job_status_code": "1"
}
}]
更新
所以我做了类似下面的事情,但我得到了 Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!
Collections.sort(compareData, new Comparator<HashMap<String, Object>>() {
@SuppressWarnings("unchecked")
@Override
public int compare(HashMap<String, Object> o1, HashMap<String, Object> o2) {
// TODO Auto-generated method stub
int i = 0;
ArrayList<?> firstArray = (ArrayList<?>) o1.get(PRE_RELEASE);
ArrayList<?> secondArray = (ArrayList<?>) o2.get(PRE_RELEASE);
do {
//System.out.println (((HashMap<String,Object>) firstArray.get(i)).get("run"));
if (((HashMap<String,Object>) firstArray.get(i)).get("run").equals("1")) {
if (((HashMap<String,Object>) firstArray.get(i)).get(JOB_STATUS).equals(((HashMap<String,Object>) secondArray.get(i)).get(JOB_STATUS))) {
return 0;
} else {
if (((HashMap<String,Object>) firstArray.get(i)).get(JOB_STATUS).equals("FAILED"))
return -1;
else if (((HashMap<String,Object>) firstArray.get(i)).get(JOB_STATUS).equals("WARNING")) {
return ((HashMap<String,Object>) firstArray.get(i)).get(JOB_STATUS).equals("FAILED") ? 1 : -1;
}
else {
return 1;
}
}
}
i++;
} while (i < firstArray.size());
return 0;
}
});
这个:
for (int j=1; i<(compareData.size() - 1); j++)
应该是
for (int j=1; j<(compareData.size() - 1); j++)
注意 (i
-> j
)
您不只是对 collection 进行排序。您首先对其进行过滤 (运行=1),然后对剩下的内容进行排序。
让我们释放一些Java8。我假设您的 pre_release collection 已排序,因为在您的示例数据中 运行=1 始终是第一个
List<MyItems> list = new LinkedList<>();
//Populate your list somehow.
list.stream()
.sorted((x1, x2) -> {
String status1 = x1.pre_release[0].job_status;
String status2 = x2.pre_release[0].job_status;
if (x1.equals(x2)) return 0;
else {
if (x1.equals("FAILED")) {
return -1;
}
else if (x1.equals("WARNING")) {
return x2.equals("FAILED") ? 1 : -1;
}
else {
return 1;
}
}
})
.collect(Collectors.toList());
如果不是这样,那么您需要更改分配 status1 和 status2 的代码以搜索 运行 = 1;
比较器需要尊重比较的传递性。意思是如果 a=b
和 b=c
则 a=c
,与 >
和 <
相同。在太多情况下,您的实施只是简单地返回 0
。我建议您研究以下方法:
List<HashMap<String, Object>> compareData = new ArrayList<>();
Collections.sort(compareData, new Comparator<HashMap<String, Object>>() {
@SuppressWarnings("unchecked")
@Override
public int compare(HashMap<String, Object> o1, HashMap<String, Object> o2) {
ArrayList<?> firstArray = (ArrayList<?>) o1.get(PRE_RELEASE);
ArrayList<?> secondArray = (ArrayList<?>) o2.get(PRE_RELEASE);
Object firstRun1 = null;
for (Object firstRun : firstArray) {
if (((HashMap<String,Object>) firstRun).get("run").equals("1")) {
firstRun1 = firstRun;
break;
}
}
Object secondRun1 = null;
for (Object secondRun : secondArray) {
if (((HashMap<String,Object>) secondRun).get("run").equals("1")) {
secondRun1 = secondRun;
break;
}
}
if (firstRun1 == secondRun1) {
return 0;
}
else if (firstRun1 == null) {
return -1;
}
else if (secondRun1 == null) {
return 1;
}
else {
String firstStatus = (String) ((HashMap<String,Object>) firstRun1).get(JOB_STATUS);
String secondStatus = (String) ((HashMap<String,Object>) secondRun1).get(JOB_STATUS);
return toNum(firstStatus).compareTo(toNum(secondStatus));
}
}
});
toNum 方法:
Integer toNum(String status) {
return "FAILED".equals(status) ? 0 : ("WARNING".equals(status) ? 1 : 2);
}
很抱歉我无法测试它,因为我缺少您的一些代码。
现在另一个建议:这段代码中有太多未经检查的转换和强制转换。我建议您直接处理某些 JSONObject
框架可能在解析 Json 时返回给您的信息,或者您将业务对象映射到真正的 POJO 而不是 Objects
的映射和列表。
我有一个数据列表,我需要按以下方式对 pre_release
下的 job_status
进行有效排序,仅适用于具有 run
的对象:1
"FAILED", "WARNING", "SUCCESS"
我正在尝试使用冒泡排序,但需要帮助
//compareData contains list of object which needs to be sorted
List<HashMap<String, Object>> compareData = new ArrayList<HashMap<String, Object>>();
HashMap<String, Object> tempObj = new HashMap<String, Object>();
for (int i=0; i<compareData.size(); i++) {
for (int j=1; i<(compareData.size() - 1); j++) {
if (Integer.parseInt(compareData.get(j-1).get(JOB_STATUS_CODE).toString()) > Integer.parseInt(compareData.get(j).get(JOB_STATUS_CODE).toString())) {
tempObj = compareData.get(j-1);
//compareData.get(j-1) = compareData.get(j);
}
}
}
比较数据
[{
"pre_release": [{
"message": "The environment GYAN-WIN2008-64-SP2-DC-1 used by this connection is inactive.",
"start_time": "2015-05-27T22:45:25.000-07:00",
"run": "1",
"job_status": "FAILED",
"job_status_code": "3"
}, {
"message": "The environment GYAN-WIN2008-64-SP2-DC-1 used by this connection is inactive.",
"start_time": "2015-05-27T22:00:25.000-07:00",
"run": "2",
"job_status": "FAILED",
"job_status_code": "3"
}, {
"message": "The environment GYAN-WIN2008-64-SP2-DC-1 used by this connection is inactive.",
"start_time": "2015-05-27T21:15:25.000-07:00",
"run": "3",
"job_status": "FAILED",
"job_status_code": "3"
}],
"task_name": "DB to DB xxx.yyy.42.62_2",
"task_id": "000ABC0G000000000007",
"production": {
"message": "The environment Redhat Linux used by this connection is inactive.",
"start_time": "2015-05-21T05:50:05.000-07:00",
"job_status": "FAILED",
"job_status_code": "3"
}
} {
"pre_release": [{
"message": "The environment Redhat Linux used by this connection is inactive.",
"start_time": "2015-05-21T05:50:05.000-07:00",
"run": "1",
"job_status": "FAILED",
"job_status_code": "3"
}, {
"message": "The environment Redhat Linux used by this connection is inactive.",
"start_time": "2015-05-21T05:45:05.000-07:00",
"run": "2",
"job_status": "FAILED",
"job_status_code": "3"
}, {
"message": "The environment Redhat Linux used by this connection is inactive.",
"start_time": "2015-05-21T05:40:05.000-07:00",
"run": "3",
"job_status": "FAILED",
"job_status_code": "3"
}],
"task_name": "IPS_WS_Test",
"task_id": "000ABC0K000000000096",
"production": {
"message": null,
"start_time": "2015-02-02T13:05:00.000-08:00",
"job_status": "SUCCESS",
"job_status_code": "1"
}
}, {
"pre_release": [{
"message": null,
"start_time": "2015-02-02T13:05:00.000-08:00",
"run": "1",
"job_status": "SUCCESS",
"job_status_code": "1"
}, {
"message": null,
"start_time": "2015-02-02T13:00:00.000-08:00",
"run": "2",
"job_status": "SUCCESS",
"job_status_code": "1"
}, {
"message": null,
"start_time": "2015-02-02T12:55:00.000-08:00",
"run": "3",
"job_status": "SUCCESS",
"job_status_code": "1"
}],
"task_name": "Logan josh mct win",
"task_id": "000ABC0Z00000000009V",
"production": {
"message": "No errors encountered.",
"start_time": "2015-05-19T13:31:28.000-07:00",
"job_status": "SUCCESS",
"job_status_code": "1"
}
}, {
"pre_release": [{
"message": null,
"start_time": "2015-05-14T07:27:10.000-07:00",
"run": "1",
"job_status": "WARNINGS",
"job_status_code": "2"
}, {
"message": "Target field [MD_COntact__c] does not exist in the object [onlytesting__c].",
"start_time": "2015-05-14T07:25:25.000-07:00",
"run": "2",
"job_status": "FAILED",
"job_status_code": "3"
}, {
"message": "Target field [MD_COntact__c] does not exist in the object [onlytesting__c].",
"start_time": "2015-05-14T07:24:55.000-07:00",
"run": "3",
"job_status": "FAILED",
"job_status_code": "3"
}],
"task_name": "Lambba",
"task_id": "000ABCI0000000002XP",
"production": {
"message": null,
"start_time": "2015-05-14T07:27:10.000-07:00",
"job_status": "WARNINGS",
"job_status_code": "2"
}
}, {
"pre_release": [{
"message": "No errors encountered.",
"start_time": "2015-05-19T13:31:28.000-07:00",
"run": "1",
"job_status": "SUCCESS",
"job_status_code": "1"
}, {
"message": "No errors encountered.",
"start_time": "2015-05-19T13:12:15.000-07:00",
"run": "2",
"job_status": "SUCCESS",
"job_status_code": "1"
}, {
"message": "No errors encountered.",
"start_time": "2015-05-19T12:51:50.000-07:00",
"run": "3",
"job_status": "SUCCESS",
"job_status_code": "1"
}],
"task_name": "chahamedidata_baja2",
"task_id": "000ABC0I000000000301",
"production": {
"message": "[ERROR] com.baja.api.bajaServiceQueryOperationTimeIntervalFaultFaultFaultMessage: Query is limited to 1 request every 250 milliseconds (there have been 64.2 milliseconds since the last request)",
"start_time": "2015-05-19T13:20:05.000-07:00",
"job_status": "SUCCESS",
"job_status_code": "1"
}
}]
更新
所以我做了类似下面的事情,但我得到了 Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!
Collections.sort(compareData, new Comparator<HashMap<String, Object>>() {
@SuppressWarnings("unchecked")
@Override
public int compare(HashMap<String, Object> o1, HashMap<String, Object> o2) {
// TODO Auto-generated method stub
int i = 0;
ArrayList<?> firstArray = (ArrayList<?>) o1.get(PRE_RELEASE);
ArrayList<?> secondArray = (ArrayList<?>) o2.get(PRE_RELEASE);
do {
//System.out.println (((HashMap<String,Object>) firstArray.get(i)).get("run"));
if (((HashMap<String,Object>) firstArray.get(i)).get("run").equals("1")) {
if (((HashMap<String,Object>) firstArray.get(i)).get(JOB_STATUS).equals(((HashMap<String,Object>) secondArray.get(i)).get(JOB_STATUS))) {
return 0;
} else {
if (((HashMap<String,Object>) firstArray.get(i)).get(JOB_STATUS).equals("FAILED"))
return -1;
else if (((HashMap<String,Object>) firstArray.get(i)).get(JOB_STATUS).equals("WARNING")) {
return ((HashMap<String,Object>) firstArray.get(i)).get(JOB_STATUS).equals("FAILED") ? 1 : -1;
}
else {
return 1;
}
}
}
i++;
} while (i < firstArray.size());
return 0;
}
});
这个:
for (int j=1; i<(compareData.size() - 1); j++)
应该是
for (int j=1; j<(compareData.size() - 1); j++)
注意 (i
-> j
)
您不只是对 collection 进行排序。您首先对其进行过滤 (运行=1),然后对剩下的内容进行排序。
让我们释放一些Java8。我假设您的 pre_release collection 已排序,因为在您的示例数据中 运行=1 始终是第一个
List<MyItems> list = new LinkedList<>();
//Populate your list somehow.
list.stream()
.sorted((x1, x2) -> {
String status1 = x1.pre_release[0].job_status;
String status2 = x2.pre_release[0].job_status;
if (x1.equals(x2)) return 0;
else {
if (x1.equals("FAILED")) {
return -1;
}
else if (x1.equals("WARNING")) {
return x2.equals("FAILED") ? 1 : -1;
}
else {
return 1;
}
}
})
.collect(Collectors.toList());
如果不是这样,那么您需要更改分配 status1 和 status2 的代码以搜索 运行 = 1;
比较器需要尊重比较的传递性。意思是如果 a=b
和 b=c
则 a=c
,与 >
和 <
相同。在太多情况下,您的实施只是简单地返回 0
。我建议您研究以下方法:
List<HashMap<String, Object>> compareData = new ArrayList<>();
Collections.sort(compareData, new Comparator<HashMap<String, Object>>() {
@SuppressWarnings("unchecked")
@Override
public int compare(HashMap<String, Object> o1, HashMap<String, Object> o2) {
ArrayList<?> firstArray = (ArrayList<?>) o1.get(PRE_RELEASE);
ArrayList<?> secondArray = (ArrayList<?>) o2.get(PRE_RELEASE);
Object firstRun1 = null;
for (Object firstRun : firstArray) {
if (((HashMap<String,Object>) firstRun).get("run").equals("1")) {
firstRun1 = firstRun;
break;
}
}
Object secondRun1 = null;
for (Object secondRun : secondArray) {
if (((HashMap<String,Object>) secondRun).get("run").equals("1")) {
secondRun1 = secondRun;
break;
}
}
if (firstRun1 == secondRun1) {
return 0;
}
else if (firstRun1 == null) {
return -1;
}
else if (secondRun1 == null) {
return 1;
}
else {
String firstStatus = (String) ((HashMap<String,Object>) firstRun1).get(JOB_STATUS);
String secondStatus = (String) ((HashMap<String,Object>) secondRun1).get(JOB_STATUS);
return toNum(firstStatus).compareTo(toNum(secondStatus));
}
}
});
toNum 方法:
Integer toNum(String status) {
return "FAILED".equals(status) ? 0 : ("WARNING".equals(status) ? 1 : 2);
}
很抱歉我无法测试它,因为我缺少您的一些代码。
现在另一个建议:这段代码中有太多未经检查的转换和强制转换。我建议您直接处理某些 JSONObject
框架可能在解析 Json 时返回给您的信息,或者您将业务对象映射到真正的 POJO 而不是 Objects
的映射和列表。