是否可以按特定顺序打印jsonObject? 这就是我所拥有的
import NPC.NPCHandler;
import NPC.NPCDrops;
import com.google.gson.*;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import java.io.FileWriter;
/**
* @author Ruud.
*/
public class Main {
public static NPCDrops npcDrops = new NPCDrops();
public static NPCHandler npcHandler = new NPCHandler();
public static void main(String args[]) {
/*for (int i = 1; i < npcs.length; i++)
System.out.println(npcs[i].absX);*/
JSONObject NPCDefinition = new JSONObject();
NPCDefinition.put("New", "Tester");
NPCDefinition.put("B", "Test");
NPCDefinition.put("A", "Test");
NPCDefinition.put("Test", "Tester");
JSONArray NPCDefinitions = new JSONArray();
NPCDefinitions.add(0, NPCDefinition);
//NPCDefinitions.add(1, NPCDefinition);
try (FileWriter file = new FileWriter("./Json/NPCDefinitions.json")) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(NPCDefinitions.toJSONString());
String prettyJsonString = gson.toJson(je);
System.out.println(prettyJsonString);
//file.write(prettyJsonString);
} catch (Exception e) {
e.printStackTrace();
}
}
}
这是它返回的内容
[
{
"New": "Tester",
"A": "Test",
"B": "Test",
"Test": "Tester"
}
]
是否可以像放入物体一样返回它? 我想要这个,因为我正在使用JSON将游戏中的NPC系统转换为新的更好的系统,但我希望命令采用人类逻辑的方式,例如
[
{
"id": 0,
"name": "Hans",
"examine": "Servant of the Duke of Lumbridge.",
"combat": 0,
"size": 1
},
{
"id": 1,
"name": "Man",
"examine": "One of many citizens.",
"combat": 2,
"drops": [
{
"id": 995,
"amount": "1000",
"chance": 0.50
},
{
"id": 4151,
"amount": "1",
"chance": 1
}
],
"size": 1
}
]
我还没有使用这些变量对它进行测试,但我确信它也会破坏订单,所以我想知道是否有办法保持这个顺序。我知道JSONObject不可能这样做,因为它是一个无序的列表或其他东西,但这不能以任何其他方式实现吗?
答案 0 :(得分:1)
JSON-Objects并不关心其属性的顺序。
可能存在处理输入顺序的JSON库的实现。但是我不建议依赖任何JSON库处理的输入顺序作为JSON-Object,并且应该保持关联的断言(键值)并且键是无序的。
因此没有内在的可能性来保留输入顺序。唯一的方法是模拟它:您必须记住订单ID并编写您自己的输出器,在输出期间考虑订单ID。
答案 1 :(得分:1)
JSON对象是无序的K / V集,但并不意味着需要严格的顺序,因此它可以完全由实现驱动。
你在这里缺少的是混合两个不同的库:JSON Simple和Gson。我以前从未使用过JSON Simple,但即使快速查看该库也会发现它的org.json.simple.JSONObject
扩展了原始HashMap
,不同的JRE版本的顺序可能不同。与org.json.simple.JSONObject
不同,Gson的原生com.google.gson.JsonObject
会保留插入顺序(请参阅JsonObject implementation的更多信息 - 只是因为它以这种方式实现)。同样的混音故事发送到org.json.simple.JSONArray
和com.google.gson.JsonArray
。因此,最简单的解决方案就是摆脱JSON Simple,而不是混合两个不同的库,只使用Gson工具,如下所示:
private static final Gson gson = new GsonBuilder()
.setPrettyPrinting()
.create();
public static void main(final String... args) {
final JsonObject npcDefinition = new JsonObject();
npcDefinition.addProperty("New", "Tester");
npcDefinition.addProperty("B", "Test");
npcDefinition.addProperty("A", "Test");
npcDefinition.addProperty("Test", "Tester");
final JsonArray npcDefinitions = new JsonArray();
npcDefinitions.add(npcDefinition);
final String json = gson.toJson(npcDefinitions);
System.out.println(json);
}
另请注意,此处不需要toString()
调用(由于内存中的字符串分配,这可能非常昂贵),因为Gson使用其JsonElement
子类非常完美。因此,保留了原始订单:
[
{
"New": "Tester",
"B": "Test",
"A": "Test",
"Test": "Tester"
}
]
由于对象是无序的,你甚至不应该依赖这个实现(我使用Gson 2.8.0) - 如果有一天新的Gson实现会破坏这个规则并打破倒退怎么办?无论出于何种原因,主要版本的兼容性(让我们说,假设的Gson 3)?这似乎与使用反射生成/使用JSON的序列化器/反序列化器相关(例如,ReflectiveTypeAdapterFactory
)。为了保证顺序,我能想到的最强大的解决方案是直接写入输出流,比如说:
@SuppressWarnings("resource")
public static void main(final String... args)
throws IOException {
final JsonWriter jsonWriter = new JsonWriter(new OutputStreamWriter(System.out));
jsonWriter.setIndent(" ");
jsonWriter.beginArray();
jsonWriter.beginObject();
jsonWriter.name("New").value("Tester");
jsonWriter.name("B").value("Tester");
jsonWriter.name("A").value("Tester");
jsonWriter.name("Test").value("Tester");
jsonWriter.endObject();
jsonWriter.endArray();
jsonWriter.flush();
}
[
{
"New": "Tester",
"B": "Tester",
"A": "Tester",
"Test": "Tester"
}
]
答案 2 :(得分:0)
定义模型的方式将影响序列化到Json的顺序。这样的事情应该有效:
public class MyModel {
public int id;
public string name;
public string examine;
public int combat;
public List<Drop> drops;
public int size;
}