javax.json奇怪的行为

时间:2016-02-03 20:32:25

标签: java json

我不明白为什么这段代码的最后一行会返回一个空字符串。

Map<String, JsonObjectBuilder> HASH_MAP = new HashMap<>();

JsonObjectBuilder one = Json.createObjectBuilder();
one.add("test1","test1");
HASH_MAP.put("one", one);

JsonObjectBuilder two = Json.createObjectBuilder();
two.add("test2","test2");
HASH_MAP.put("two", two);

JsonObjectBuilder toReturn = Json.createObjectBuilder();
JsonArrayBuilder l1 = Json.createArrayBuilder();
for (Map.Entry<String, JsonObjectBuilder> l : HASH_MAP.entrySet()) {
    l1.add(l.getValue());
}

toReturn.add("l1", l1);
toReturn.add("otherParam", "value2");
String strJSON = toReturn.build().toString();
System.out.println("JSON1: " + strJSON);
System.out.println("JSON2: " + HASH_MAP.get("one").build().toString());

这是输出:

Info:   JSON1: {"l1":[{"test1":"test1"},{"test2":"test2"}],"otherParam":"value2"}
Info:   JSON2: {}

我想第二个JSON是{"test1":"test1"}。我错了?
该问题似乎与.build()函数相关联,该函数将添加到HASH_MAP的元素的所有 valueMap 设置为null(请参见图像)。 enter image description here

如何将值保留在HASH_MAP内未触动?

3 个答案:

答案 0 :(得分:5)

build() JsonObject JsonObjectBuilder后,构建器已清除以准备重复使用。为了说明这一点:

JsonObjectBuilder b = Json.createObjectBuilder();
b.add("foo", "bar");
JsonObject o = b.build();
JsonObject p = b.build();
System.out.println(o.toString()); // {"foo":"bar"}
System.out.println(p.toString()); // {}

当你这样做时

l1.add(l.getValue()); // l.getValue() is (JsonObjectBuilder) one at some time
{p> build()one上被称为隐式,因此它已被清空。

然后在这里:

System.out.println("JSON2: " + HASH_MAP.get("one").build().toString());

您构建空JsonObject的表示。

要迁移它,您可以在散列映射中存储JsonObjects而不是JsonObjectBuilders:

Map<String, JsonObject> HASH_MAP = new HashMap<>();

JsonObjectBuilder one = Json.createObjectBuilder();
one.add("test1","test1");
HASH_MAP.put("one", one.build());

JsonObjectBuilder two = Json.createObjectBuilder();
two.add("test2","test2");
HASH_MAP.put("two", two.build());

JsonObjectBuilder toReturn = Json.createObjectBuilder();
JsonArrayBuilder l1 = Json.createArrayBuilder();
for (Map.Entry<String, JsonObject> l : HASH_MAP.entrySet()) {
    l1.add(l.getValue());
}

toReturn.add("l1", l1);
toReturn.add("otherParam", "value2");
String strJSON = toReturn.build().toString();
System.out.println("JSON1: " + strJSON);
System.out.println("JSON2: " + HASH_MAP.get("one").toString());

现在它应该按预期工作。

答案 1 :(得分:3)

请记住,对build()的调用会刷新存储在对象one JSonObjectBuilder中的值,因此您只能调用一次方法build(),如果再次调用它,则转到表示空JSonObject。例如:

one.add("test1","test1");   
System.out.println(one.build())
System.out.println(one.build())

输出:

{"test1":"test1"}
{}

如果您真的想再次调用它,则必须再次添加所需的值。例如:

one.add("test1","test1");
System.out.println(one.build())
one.add("test1","test1")
System.out.println(one.build())

输出:

{"test1":"test1"}
{"test1":"test1"}

正如@Ctx所说,你可以放置你的地图JsonObjects而不是JsonObjectBuilders,所以把你的地图值作为方法build()调用返回的JsonObject。

例如:

HASH_MAP.put("one", one.build());

答案 2 :(得分:0)

如前所述,当您调用build()时,提供的JsonObjectBuilder实现会刷新。

最佳解决方案是基于JsonObjectBuilder接口实现您自己的非刷新构建器:

new_frame = cv2.remap(prev_frame, pixel_map)

整篇文章:http://www.amihaiemil.com/2017/06/14/non-flushable-jsonobjectbuilder.html