在java中是否可以从JSONObject获取不同的值

在java中是否可以从JSONObject获取不同的值,java,json,unique,distinct,Java,Json,Unique,Distinct,我有一个包含500k对象的json文件,其格式如下: "WORKORDER": [ { "Attributes": { "SITEID": { "content": "BEDFORD" }, "WONUM": { "cont

我有一个包含500k对象的json文件,其格式如下:

"WORKORDER": [
            { 
                "Attributes": { 
                    "SITEID": {
                        "content": "BEDFORD"
                    },
                    "WONUM": {
                        "content": "1000"
                    },
                    "WOPRIORITY": {
                        "content": 2
                    },
                    "WORKTYPE": {
                        "content": "CM"
                    }
                }
            },
            { 
                "Attributes": { 
                    "SITEID": {
                        "content": "BEDFORD"
                    },
                    "WONUM": {
                        "content": "1000-10"
                    },
                    "WORKTYPE": {
                        "content": "CM"
                    }
                }
            }
我将获得如下不同的值:

for (int i = 0; i < WORKORDER.length(); i++) {  
                         JSONObject obj = WORKORDER.getJSONObject(i); 

                         JSONObject att = obj.getJSONObject("Attributes"); 

                         if( att.has(col)){ // getting col from params in the servlet

                             JSONObject column = att.getJSONObject(col);
                           Object  colval =   column.get("content");

                           if(!(list.contains(colval))) {
                              out.println( colval); 
                               list.add(colval);

                             }
for(inti=0;i
但只需要5000个对象就需要很长时间


是否有任何方法可以在不解析整个Json文件的情况下获取任何列的不同值,否则只解析所需的列。

您正在迭代一个包含500k个元素的Json。对于每个元素,您都要检查它之前是否添加到
列表中。这意味着您的逻辑将迭代列表500k次

相反,您应该使用
HashSet
,首先是
集合
防止重复值。因此您只需要
集合。添加(值)
,但最有趣的是实例具有恒定的复杂性值。因为它使用bucket来组织值,所以不必完全迭代
集合

你可以阅读更多关于这方面的内容

请注意,HashSet给出了O(1)的摊销和平均时间性能,而不是最坏的情况。这意味着,我们可能会不时遇到O(n)操作。 因此,当垃圾箱太拥挤时,我们只需创建一个新的、更大的数组,并将元素复制到其中

请注意,要使用任何
Hash#####
实现,您需要确保存储的实例实现了
hashCode
等于
。您可以了解更多信息

现在来看解决方案:

Set<Object> sets = new HashSet<>();
for (int i = 0; i < WORKORDER.length(); i++) {  
    // ...
    Object  colval =   column.get("content");
    if(sets.add(colval)){ //`add` return true if it wasn't present already.
        out.println( colval); 
    }
}
然后对这两种方法进行了基本基准测试,结果如下:

public static void main(String[] args) throws Exception {
    final int jsonLength = 500_000;
    JSONObject json = createDummyJson(jsonLength);
    long start = System.currentTimeMillis();
    List<Object> list = parseJson(json);
    long end = System.currentTimeMillis();
    System.out.format("List - Run in %d ms for %d items and output %d lines%n", end-start, jsonLength, list.size());

    start = System.currentTimeMillis();
    Set<Object> set = parseJsonSet(json);
    end = System.currentTimeMillis();
    System.out.format("Set - Run in %d ms for %d items and output %d lines%n", end-start, jsonLength, set.size());
}

public static List<Object> parseJson(JSONObject json) {
    String col = "columnC";

    JSONArray array = json.getJSONArray("order");

    List<Object> list = new ArrayList<>();
    for (int i = 0; i < array.length(); i++) {
        JSONObject obj = array.getJSONObject(i);
        JSONObject att = obj.getJSONObject("Attributes");
        if (att.has(col)) { // getting col from params in the servlet
            JSONObject column = att.getJSONObject(col);
            Object colval = column.get("content");

            if (!(list.contains(colval))) {
                //System.out.println(colval);
                list.add(colval);
            }
        }
    }

    return list;
}

public static Set<Object> parseJsonSet(JSONObject json) {
    String col = "columnC";

    JSONArray array = json.getJSONArray("order");

    Set<Object> set = new HashSet<>();
    for (int i = 0; i < array.length(); i++) {
        JSONObject obj = array.getJSONObject(i);
        JSONObject att = obj.getJSONObject("Attributes");
        if (att.has(col)) { // getting col from params in the servlet
            JSONObject column = att.getJSONObject(col);
            Object colval = column.get("content");

            if (set.add(colval)) {
                //System.out.println(colval);
            }
        }
    }

    return set;
}
publicstaticvoidmain(字符串[]args)引发异常{
最终内部jsonLength=500_000;
JSONObject json=createDummyJson(jsonLength);
长启动=System.currentTimeMillis();
List=parseJson(json);
long end=System.currentTimeMillis();
System.out.format(“列表-在%d毫秒内运行%d个项目并输出%d行%n)”,结束-开始,jsonLength,List.size();
start=System.currentTimeMillis();
Set=parseJsonSet(json);
end=System.currentTimeMillis();
System.out.format(“设置-在%d毫秒内运行%d个项目并输出%d行%n)”,结束-开始,jsonLength,Set.size();
}
公共静态列表解析json(JSONObject json){
String col=“columnC”;
JSONArray数组=json.getJSONArray(“订单”);
列表=新的ArrayList();
对于(int i=0;i
列表-在5993毫秒内运行500000个项目,输出46971行
设置-在62毫秒内运行500000个项目,输出46971行

我甚至访问了一个有500万行的JSON(删除了永远不会结束的列表)

设置-在6436毫秒内运行5000000个项目,输出468895行


重要提示:每次新插入时,请删除控制台中打印的行,这将减少一点执行时间。您可以使用
设置
而不是
列表
(如果
列表
代表
列表
),这样会“更简单”现在要直接过滤JSON…除非您可以更改JSON的生成,否则您仍然需要读取JSON(
JSONObject
只是一个解析器)。您可以尝试将其转换为csv,然后获取所需的column@AxelH当使用集合时,它会加速解析吗?@PankajSinghal,但是转换成csv比抓取还需要时间!!是和否。这取决于你所采用的实现。使用
哈希集合可以做到这一点,因为它使用bucket。目前,这是s是杀死你的
contains
方法,它需要迭代JSON中每个元素的列表。起初这没关系,但当你已经有1000个项目时,这些项目将被迭代40万次以上。@AnasElbenney请注意最后一部分,使用
列。get
使用此逻辑不安全,请使用
getString(“content”)
取而代之。(忘了你已经显示了JSON…)但我不知道用户是否选择了字符串列或数字!很抱歉,它做得太长了,两个(set和list)的时间都一样好@AnasElbenney我将生成一个伪JSON来做一些测试。完成后我会回复你(可能是今晚格林威治标准时间)@AnasElbenney我使用一个“相似”的json运行,并验证了差异。如果它不起作用,那么这就不是需要时间的
集。。。
public static void main(String[] args) throws Exception {
    final int jsonLength = 500_000;
    JSONObject json = createDummyJson(jsonLength);
    long start = System.currentTimeMillis();
    List<Object> list = parseJson(json);
    long end = System.currentTimeMillis();
    System.out.format("List - Run in %d ms for %d items and output %d lines%n", end-start, jsonLength, list.size());

    start = System.currentTimeMillis();
    Set<Object> set = parseJsonSet(json);
    end = System.currentTimeMillis();
    System.out.format("Set - Run in %d ms for %d items and output %d lines%n", end-start, jsonLength, set.size());
}

public static List<Object> parseJson(JSONObject json) {
    String col = "columnC";

    JSONArray array = json.getJSONArray("order");

    List<Object> list = new ArrayList<>();
    for (int i = 0; i < array.length(); i++) {
        JSONObject obj = array.getJSONObject(i);
        JSONObject att = obj.getJSONObject("Attributes");
        if (att.has(col)) { // getting col from params in the servlet
            JSONObject column = att.getJSONObject(col);
            Object colval = column.get("content");

            if (!(list.contains(colval))) {
                //System.out.println(colval);
                list.add(colval);
            }
        }
    }

    return list;
}

public static Set<Object> parseJsonSet(JSONObject json) {
    String col = "columnC";

    JSONArray array = json.getJSONArray("order");

    Set<Object> set = new HashSet<>();
    for (int i = 0; i < array.length(); i++) {
        JSONObject obj = array.getJSONObject(i);
        JSONObject att = obj.getJSONObject("Attributes");
        if (att.has(col)) { // getting col from params in the servlet
            JSONObject column = att.getJSONObject(col);
            Object colval = column.get("content");

            if (set.add(colval)) {
                //System.out.println(colval);
            }
        }
    }

    return set;
}