如何使用Java从JSONArray中去重并排序对象

9

我的JSON数据是:

[
   {
      "distance":32,
      "stationCode":"MIG",
      "name":"Midghat",
      "platforms":"2"
   },
   {
      "distance":32,
      "stationCode":"MIG",
      "name":"Midghat",
      "platforms":"2"
   },
   {
      "distance":69,
      "stationCode":"MDDP",
      "name":"Mandideep",
      "platforms":"2"
   },
   {
      "distance":69,
      "stationCode":"MDDP",
      "name":"Mandideep",
      "platforms":"2"
   },
   {
      "distance":18,
      "stationCode":"HBD",
      "name":"Hoshangabad",
      "platforms":"2"
   },
   {
      "distance":18,
      "stationCode":"HBD",
      "name":"Hoshangabad",
      "platforms":"2"
   },
   {
      "distance":37,
      "stationCode":"CHQ",
      "name":"Choka",
      "platforms":"2"
   },
   {
      "distance":37,
      "stationCode":"CHQ",
      "name":"Choka",
      "platforms":"2"
   },
   {
      "distance":85,
      "stationCode":"HBJ",
      "name":"Habibganj",
      "platforms":"5"
   },
   {
      "distance":85,
      "stationCode":"HBJ",
      "name":"Habibganj",
      "platforms":"5"
   },
   {
      "distance":0,
      "stationCode":"ET",
      "name":"ItarsiJn",
      "platforms":"28"
   },
   {
      "distance":8,
      "stationCode":"PRKD",
      "name":"Powerkheda",
      "platforms":"2"
   },
   {
      "distance":8,
      "stationCode":"PRKD",
      "name":"Powerkheda",
      "platforms":"2"
   },
   {
      "distance":55,
      "stationCode":"ODG",
      "name":"ObaidullaGanj",
      "platforms":"2"
   },
   {
      "distance":55,
      "stationCode":"ODG",
      "name":"ObaidullaGanj",
      "platforms":"2"
   },
   {
      "distance":44,
      "stationCode":"BKA",
      "name":"Barkhera",
      "platforms":"2"
   },
   {
      "distance":44,
      "stationCode":"BKA",
      "name":"Barkhera",
      "platforms":"2"
   },
   {
      "distance":79,
      "stationCode":"MSO",
      "name":"Misrod",
      "platforms":"2"
   },
   {
      "distance":79,
      "stationCode":"MSO",
      "name":"Misrod",
      "platforms":"2"
   },
   {
      "distance":25,
      "stationCode":"BNI",
      "name":"Budni",
      "platforms":"2"
   },
   {
      "distance":25,
      "stationCode":"BNI",
      "name":"Budni",
      "platforms":"2"
   },
   {
      "distance":91,
      "stationCode":"BPL",
      "name":"BhopalJn",
      "platforms":"6"
   },
   {
      "distance":63,
      "stationCode":"ITKL",
      "name":"ItayaKalan",
      "platforms":"2"
   },
   {
      "distance":63,
      "stationCode":"ITKL",
      "name":"ItayaKalan",
      "platforms":"2"
   }
]

我希望它可以按照距离排序并删除重复的站点代码。我尝试过使用简单的if-else语句,但这个过程太麻烦了。有没有同样用于排序的快捷方式?

发布你已经尝试过的代码和出现的错误 :) 这样你学习会更容易,我们提供帮助也会更方便! - Bruno Caceiro
3个回答

9

我一段时间之前写了这个工具,它可以对一个JSONArrayJSONObjects 进行排序。唯一的条件是你的JSONobjects 必须包含你想要根据的 keys 进行 sort(如果你想根据多个键进行排序,它也接受一组键)。

import java.util.Collections;
import java.util.Comparator;
import java.util.Random;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
public class JSONArraySort {
    @SuppressWarnings("unchecked")
    public static void sortASCE(JSONArray array, Object key) {
        Object[] keys = { key };
        Collections.sort(array, new JSONArrayComparator(false, keys));
    }
    @SuppressWarnings("unchecked")
    public static void sortDESC(JSONArray array, Object key) {
        Object[] keys = { key };
        Collections.sort(array, new JSONArrayComparator(true, keys));
    }
    @SuppressWarnings("unchecked")
    public static void sortASCE(JSONArray array, Object[] key) {
        Collections.sort(array, new JSONArrayComparator(false, key));
    }
    @SuppressWarnings("unchecked")
    public static void sortDESC(JSONArray array, Object[] key) {
        Collections.sort(array, new JSONArrayComparator(true, key));
    }
    private static class JSONArrayComparator implements Comparator<JSONObject> {
        private final Object[] KEYS;
        private final boolean DESC;
        public JSONArrayComparator(boolean DESC, Object[] KEYS) {
            this.KEYS = KEYS;
            this.DESC = DESC;
        }
        @Override
        public int compare(JSONObject object1, JSONObject object2) {
            int length = KEYS.length;
            for(int i = 0 ; i < length ; i++){
                String KEY = KEYS[i].toString();
                Object one = object1.get(KEY);
                Object two = object2.get(KEY);
                if(Number.class.isAssignableFrom(one.getClass()) && Number.class.isAssignableFrom(two.getClass())){
                    Double numOne = Number.class.cast(one).doubleValue();
                    Double numTwo = Number.class.cast(two).doubleValue();
                    int compared = 0;
                    if(DESC){
                        compared = numTwo.compareTo(numOne);
                    }else{
                        compared = numOne.compareTo(numTwo);
                    }
                    if(i == KEYS.length - 1 || compared != 0){
                        return compared;
                    }
                }else{
                    int compared = 0;
                    if(DESC){
                        compared = two.toString().compareTo(one.toString());
                    }else{
                        compared = one.toString().compareTo(two.toString());
                    }
                    if(i == KEYS.length - 1 || compared != 0){
                        return compared;
                    }
                }
            }
            // this shouldn't happen.
            return 0;
        }
    }
        //testing...
    public static void main(String... args) {
        JSONArray array1 = new JSONArray();
        for(int i = 0 ; i < 100 ; i++){
            Random random = new Random();
            int num1 = random.nextInt(10);
            int num2 = random.nextInt(10);
            JSONObject object = new JSONObject();
            object.put("num1", num1);
            object.put("num2", num2);
            array1.add(object);
        }
        String[] keys = { "num1", "num2" };
        sortASCE(array1, keys);
        System.out.println(array1.toString());
    }
}

现在如果你想要删除重复项,你可以通过 迭代 它们来实现。
Set<String> stationCodes=new HashSet<String>();
JSONArray tempArray=new JSONArray();
for(int i=0;i<yourJSONArray.size();i++){
   String  stationCode=yourJSONArray.getJSONObject(i).getString("stationCode");
   if(stationsCodes.contains(stationCode){
     continue;
   }
   else{
      stationsCodes.add(stationCode);
      tempArray.add(yourJSONArray.getJSONObject(i));
   }

}


yourJSONArray= tempArray; //assign temp to original

//here how you can sort it using utility above:
JSONArraySort.sortASCE(yourJSONArray,"distance");

谢谢,排序的部分很有效。过滤重复项也和我的其他逻辑一起完成了 :) 用这个排序功能省了很多时间 :) - Govind Mantri
@GovindMantri,厉害了我的哥,你应该知道可以使用多个键进行降序排序。 - nafas

1

没有直接的方法,但您可以按照下面提到的方式进行操作:

  1. 使用 org.codehaus.jackson.map.ObjectMapper 将 JsonObject 转换为 Java 对象列表

  2. 使用 Java Map 使其唯一(将 key = stationCode,Java 对象作为对象)

  3. 根据距离对地图数据进行排序。


当然有直接的排序方式 :) - nafas

0
Here is the code for joining '2' JSONArrays and removing duplicates from the joined JSONArray, using ArrayList<String>..contains() method:

    import java.util.ArrayList;
    import java.util.List;

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

    /**
     * @author RAM K K
     * @gmail kkram523@gmail.com
     * 
     */

public class JSONOperations {

    public static void main(String[] args) {

        String s3;

        String s1 = "[{\"name\": \"Bob\", \"car\": \"Ford\"},{\"name\": \"Steve\", \"car\": \"Mercedes Benz\"},{\"name\": \"Bob\", \"car\": \"Ford\"},{\"name\": \"Bob\", \"car\": \"Ford\"},{\"name\": \"Bob\", \"car\": \"Ford\"},{\"name\": \"Bob\", \"car\": \"Ford\"},{\"name\": \"Mary\", \"car\": \"Fiat\"}]";
        String s2 = "[{\"name\": \"Mack\", \"car\": \"VW\"},{\"name\": \"Steve\", \"car\": \"Mercedes Benz\"},{\"name\": \"Bob\", \"car\": \"Ford\"}]";
        try {
            JSONArray sourceArray = new JSONArray(s2);
            JSONArray destinationArray = new JSONArray(s1);

            System.out.println(sourceArray);
            System.out.println(destinationArray);

            for (int i = 0; i < sourceArray.length(); i++) {
                destinationArray.put(sourceArray.getJSONObject(i));
            }

            System.out.println(destinationArray);
            System.out.println("JSONArray Size is: " + destinationArray.length());
            List<String> list = new ArrayList<String>();
            for (int i = 0; i < destinationArray.length(); i++) {
                if (!list.contains(destinationArray.get(i).toString())) {
                    list.add(destinationArray.get(i).toString());
                }
            }

            System.out.println("LIST: " + list);
            System.out.println("LIST Size: " + list.size());

            JSONArray distinctJSONArray = new JSONArray(list.toString());
            System.out.println(distinctJSONArray.length());
            for (int i = 0; i < distinctJSONArray.length(); i++) {
                JSONObject JSON = (JSONObject) distinctJSONArray.getJSONObject(i);
                System.out.println(JSON);
            }

            s1 = s1.substring(s1.indexOf("[") + 1, s1.lastIndexOf("]"));
            s2 = s2.substring(s2.indexOf("[") + 1, s2.lastIndexOf("]"));

            s3 = "[" + s1 + "," + s2 + "]";
            System.out.println(new JSONArray(s3));

        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

这并不是问题所要求的。 “我希望它按距离排序并删除重复的stationCode。” 此外,您发了两次相同的帖子。 - Radiodef
请参见主题为“如何使用Java从JSONArray中删除重复项并对其进行排序”的内容。 - KodandaRamu Kodaconti
这不是网站的工作方式。问题标题只是一个介绍。即使这是网站的工作方式,它也会强化我的观点,因为你的代码没有展示如何对列表进行排序。 - Radiodef
是的,我的代码不是用来排序的,而是用来去重的! - KodandaRamu Kodaconti

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接