如何在数组中标记重复项?

时间:2011-03-20 03:37:47

标签: java arrays json

我想知道一种标记数组中值的方法,删除重复项并将Java中的一些数据组合

我使用lat,long和描述记录地理位置,这是在JSON数组中编码,如下所示:

[{"lon": 0.001, "lat": 0.001, "desc": test}, {"lon": 0.001, "lat": 0.001, "desc": test2}]

我希望能够在保留数组的“desc”部分的同时删除重复的地理位置,例如

[{"lon": 0.001, "lat": 0.001, "desc": test, test2}]

修改: 这就是我目前正在做的事情:

//Store locPoints from server in JSONArray
JSONArray jPointsArray = new JSONArray(serverData); 
List<JSONObject> jObjects = new ArrayList<JSONObject>();
List<JSONObject> seenObjects = new ArrayList<JSONObject>();

 for(int i = 0; i < jPointsArray.length(); ++i)
{
 jObjects.add(jPointsArray.getJSONObject(i));
}        
 for (JSONObject obj : jObjects) 
                {
                    //This always returns true
                    if (!seenObjects.contains(obj))// && !seenObjects.contains(obj.get("lon")))
                    {

                        Log.i("Sucess", "Huzzah!");
                        seenObjects.add(obj);
                    }
                    else 
                    {
                         //merge the 'desc' field in 'obj' with the 'desc' field in
                         JSONObject original = (JSONObject)seenObjects.get(seenObjects.indexOf(obj));
                         JSONObject update = obj;
                         original.put("desc", original.get("desc") + ", " + update.get("desc"));
                         seenObjects.get(seenObjects.indexOf(obj)).get("desc"));

                    }
                }

2 个答案:

答案 0 :(得分:2)

您可以执行以下操作:

//assuming that the array you are filtering is called 'myArray'
List<Object> seenObjects = new ArrayList<Object>();
for (Object obj : myArray) {
    if (! seenObjects.contains(obj)) {
        seenObjects.add(obj);
    }
    else {
        //merge the 'desc' field in 'obj' with the 'desc' field in
        //'seenObjects.get(seenObjects.indexOf(obj))'
    }
}

请注意,只有在您比较的对象具有equals()hashCode()的实现时才能执行此操作(在您的情况下,它们应该只考虑'lat'和'lon'字段)。

更新

以下是一些完整的示例代码:

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

import org.json.simple.JSONObject;
import org.json.simple.JSONValue;

public class JsonMergeTest {
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static void main(String[] args) {
        List<Object> myArray = new ArrayList<Object>();
        myArray.add(MyJsonObject.parse("{\"lon\": 0.001, \"lat\": 0.001, \"desc\": \"test\"}"));
        myArray.add(MyJsonObject.parse("{\"lon\": 0.001, \"lat\": 0.001, \"desc\": \"test2\"}"));

        List seenObjects = new ArrayList<Object>();
        for (Object obj : myArray) {
            if (! seenObjects.contains(obj)) {
                seenObjects.add(obj);
            }
            else {
                //merge the 'desc' field in 'obj' with the 'desc' field in the list
                MyJsonObject original = (MyJsonObject)seenObjects.get(seenObjects.indexOf(obj));
                MyJsonObject update = (MyJsonObject)obj;
                original.put("desc", original.get("desc") + ", " + update.get("desc"));
            }
        }

        for (MyJsonObject obj : (List<MyJsonObject>)seenObjects) {
            System.out.println(obj.toJSONString());
        }
    }

    private static class MyJsonObject extends JSONObject  {
        @Override
        public boolean equals(Object obj) {
            if (obj == null || ! (obj instanceof MyJsonObject) || ! this.containsKey("lat") || ! this.containsKey("lon")) {
                return super.equals(obj);
            }
            MyJsonObject jsonObj = (MyJsonObject)obj;
            return this.get("lat").equals(jsonObj.get("lat")) && this.get("lon").equals(jsonObj.get("lon"));
        }

        @Override
        public int hashCode() {
            if (! this.containsKey("lat") || ! this.containsKey("lon")) {
                return super.hashCode();
            }
            return this.get("lat").hashCode() ^ this.get("lon").hashCode();
        }

        @SuppressWarnings("unchecked")
        public static Object parse(String json) {
            Object parsedJson = JSONValue.parse(json);
            if (! (parsedJson instanceof JSONObject)) {
                return parsedJson;
            }

            MyJsonObject result = new MyJsonObject();
            result.putAll((JSONObject)parsedJson);
            return result;
        }
    }
}

答案 1 :(得分:2)

您可以使用GSon。然后按照以下步骤操作:

1。在Java中定义等效的POJO,以映射JSON字符串

public class Location implements Comparable<Location> {
    public String lon;
    public String lat;
    public String desc;

    @Override
    public String toString() {
        return "<lon: " + lon +", lat: "+ lat +", desc: " + desc +">";
    }

    @Override
    public boolean equals(Object obj) {
        return ((Location)obj).lon.equals(lon) && ((Location)obj).lat.equals(lat); 
    }

    public int compareTo(Location obj) {
        return ((Location)obj).lon.compareTo(lon) + ((Location)obj).lat.compareTo(lat);
    }


}

2. 编写合并类似位置的代码。好的,这是周日,让我们这样做:)

public static void main(String[] args){
      //Some test data
    String s = "[" +
            " {\"lon\": 0.001, \"lat\": 0.001, \"desc\": \"test\"}," +
            " {\"lon\": 0.002, \"lat\": 0.001, \"desc\": \"test3\"}," +
            " {\"lon\": 0.002, \"lat\": 0.005, \"desc\": \"test4\"}," +
            " {\"lon\": 0.002, \"lat\": 0.001, \"desc\": \"test5\"}," +
            " {\"lon\": 0.001, \"lat\": 0.001, \"desc\": \"test2\"}]";
    Gson gson = new Gson();
    Location[] al = gson.fromJson(s, Location[].class);
    List<Location> tl = Arrays.asList(al);

     //lets sort so that similar locations are grouped
    Collections.sort(tl);
    List<Location> fl = new ArrayList<Location>();
    Location current = null;

     //merge!
    for(Iterator<Location> it = tl.iterator(); it.hasNext();){
        current = current==null?it.next():current;
        Location ltmp = null;
        while(it.hasNext() && (ltmp = it.next()).equals(current))
            current.desc = current.desc + "," + ltmp.desc;
        fl.add(current);
        current = ltmp;
    }

       //convert back to JSON?
    System.out.println(gson.toJson(fl));

}

3。输出

[{"lon":"0.002","lat":"0.005","desc":"test4"},
{"lon":"0.002","lat":"0.001","desc":"test3,test5"},
{"lon":"0.001","lat":"0.001","desc":"test,test2"}]