gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 06:12:44 26 4
gpt4 key购买 nike

我有一个包含 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);

}

但是只有 5000 个对象就需要很长时间!

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

最佳答案

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

相反,您应该使用HashSet,首先,Set 可以防止重复值。因此,您只需要 set.add(value) 但最有趣的是实例具有恒定的复杂性值。由于它使用存储桶来组织值,因此不必完全迭代Set

您可以阅读更多相关信息 in amit answer's about How can a HashSet offer constant time add operation?

Note that HashSet gives amortized and average time performance of O(1), not worst case. This means, we can suffer an O(n) operation from time to time. So, when the bins are too packed up, we just create a new, bigger array, and copy the elements to it.

请注意,要使用任何 Hash#### 实现,您需要确保您存储的实例正确实现 hashCodeequals 。您可以了解更多相关信息in the community post about What issues should be considered when overriding equals and hashCode in Java? .

现在给出解决方案:

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);
}
}

我保留了Object类型,但是应该正确键入,至少要确保这些实例根据需要实现这些方法。

colval 是一个 Object,它可能无法正确实现所需的方法,因此我建议您正确解析它。您应该改用column.getString("content) 或检查实例类型。

<小时/>

为了验证这一点,我使用了一种方法来创建一个假 JSON:

public static JSONObject createDummyJson(int items) {
JSONObject json = new JSONObject();
JSONArray orders = new JSONArray();
json.put("order", orders);

JSONObject attributes;
JSONObject item;
JSONObject order;

Random rand = new Random();
String[] columns = {"columnA", "columnB", "columnC", "columnD"};

for(int i = 0; i < items; ++i) {
order = new JSONObject();
attributes = new JSONObject();
order.put("Attributes", attributes);
orders.put(order);

for(int j = 0; j < rand.nextInt(1000) % columns.length; ++j) {
item= new JSONObject();
long rValue = rand.nextLong();
item.put("content", j%3 == 0 ? ("" + rValue ) : rValue );
attributes.put(columns[j], item);
}
}
return 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;
}

List - Run in 5993 ms for 500000 items and output 46971 lines
Set - Run in 62 ms for 500000 items and output 46971 lines

我什至使用了 5M 行的 JSON(删除了永远不会结束的列表)

Set - Run in 6436 ms for 5000000 items and output 468895 lines

重要的是,删除每次新插入时在控制台中打印的行,这会稍微减少执行时间。

关于java - 是否可以从 java 中的 JSONObject 获取不同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49877006/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com