93

I am using the JSON library provided here http://www.json.org/java/index.html to convert a json string I have to CSV. But the problem I have is, the order of the keys is lost after conversion.

This is the conversion code:

    JSONObject jo = new JSONObject(someString);
    JSONArray ja = jo.getJSONArray("items");
    String s = CDL.toString(ja);
    System.out.println(s);

This is the content of "someString":

{
    "items":
    [
        {
            "WR":"qwe",
            "QU":"asd",
            "QA":"end",
            "WO":"hasd",
            "NO":"qwer"
        },
    ]
}

This is the result:

WO,QU,WR,QA,NO
hasd,asd,qwe,end,qwer

While what I expect is to keep the order of the keys:

WR,QU,QA,WO,NO
qwe,asd,end,hasd,qwer

Is there any way I can have this result using this library? If not, is there any other library that will provide the capability to keep the order of keys in the result?

Hery
  • 7,443
  • 9
  • 36
  • 41
  • 4
    Dictionaries are unsorted. I don't even think JSON guarantees order. – Falmarri Dec 23 '10 at 03:47
  • 4
    thanks for the info. But I have no choice but to use JSON in my application and my application needs to keep the order of the keys :( – Hery Dec 23 '10 at 05:17
  • In my case the issue isn't the lack of an order but that it is non-deterministic. Sometimes I get key `foo` before key `bar` and sometimes `bar` before `foo`. This makes it difficult to write tests for. – Sridhar Sarnobat Oct 14 '15 at 23:55
  • I've also encountered this need, but it's for fast log comparison during real-time testing. I need to compare newly generated logs to previously generated logs in real-time for a high through-put application. There are other ways to do it, but I'd prefer the logs be in JSON format. However, to minimize CPU use, I'm writing my own direct-to-string JSON writer. I don't need the internal structure at all, and I can maintain key order for fast string comparisons of logs. There are good reasons to want predictable order. – Joe Lapp Jan 27 '17 at 22:31
  • write your own code to convert JSON to a specificaly ordered CSV file, that way you respect what both formats are supposed to be. – Martijn Scheffer Apr 26 '19 at 13:18

18 Answers18

105

There are (hacky) ways to do it ... but you shouldn't.

In JSON, an object is defined thus:

An object is an unordered set of name/value pairs.

See http://json.org.

Most implementations of JSON make no effort to preserve the order of an object's name/value pairs, since it is (by definition) not significant.

If you want order to be preserved, you need to redefine your data structure; e.g.

{
    "items":
    [
        [
            {"WR":"qwe"},
            {"QU":"asd"},
            {"QA":"end"},
            {"WO":"hasd"},
            {"NO":"qwer"}
        ],
    ]
}

or more simply:

{
    "items":
    [
        {"WR":"qwe"},
        {"QU":"asd"},
        {"QA":"end"},
        {"WO":"hasd"},
        {"NO":"qwer"}
    ]
}

FOLLOWUP

Thanks for the info, but I have no choice but to use JSON in my application and my application needs to keep the order of the keys regardless of the definition of JSON object... I am not allowed to change the format of the JSON file as well...

You need to have a hard conversation with whoever designed that file structure and won't let you change it. It is / they are plain wrong. You need to convince them.

If they really won't let you change it:

  • You should insist on not calling it JSON ... 'cos it isn't.
  • You should point out that you are going to have to write / modify code specially to handle this "not JSON" format ... unless you can find some JSON implementation that preserves the order. If they are a paying client, make sure that they pay for this extra work you have to do.
  • You should point out that if the "not JSON" needs to be used by some other tool, it is going to be problematic. Indeed, this problem will occur over and over ...

This kind of thing as really bad. On the one hand, your software will be violating a well established / long standing specification that is designed to promote interoperability. On the other hand, the nit-wits who designed this lame (not JSON!) file format are probably slagging off other people's systems etc 'cos the systems cannot cope with their nonsense.

UPDATE

It is also worth reading what the JSON RFC (RFC 7159) says on this subject. Here are some excerpts:

In the years since the publication of RFC 4627, JSON has found very wide use. This experience has revealed certain patterns, which, while allowed by its specifications, have caused interoperability problems.

JavaScript Object Notation (JSON) is a text format for the serialization of structured data. ...

JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and arrays).

An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array.

JSON parsing libraries have been observed to differ as to whether or not they make the ordering of object members visible to calling software. Implementations whose behavior does not depend on member ordering will be interoperable in the sense that they will not be affected by these differences.

Community
  • 1
  • 1
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Thanks for the info, but I have no choice but to use JSON in my application and my application needs to keep the order of the keys regardless of the definition of JSON object... I am not allowed to change the format of the JSON file as well... – Hery Dec 23 '10 at 05:19
  • Just noticed your edit. I appreciate the advice, but the "JSON-like" format really cannot be changed... So I just have to suck it up haha – Hery Dec 23 '10 at 16:14
  • @StephenC : Nice answer. I am struggling with the same problem and its creating duplicity in my paginated ListView. What the heck !!! No solutions ? – Yogesh Somani Nov 08 '12 at 06:02
  • 4
    @YogeshSomani - the "solution" is to get hold of a proper JSON library, and "hack" it so that it preserves the key order. See gary's answer for an example. But you shouldn't expect a standard JSON library to do this because it is a BAD IDEA to encourage abuse of the JSON specification like this. The real solution is to fix your application to use JSON properly. – Stephen C Nov 08 '12 at 07:20
  • 22
    its great to be purest and absolute, but let's not kid ourselves, there are real world scenarios where a JSON file needs its ordering of its defined values preserved. To pass and accept them in any order is a fundamental json approach, but I consider that dfferent than the ability to be able to take a json document and serialize / deserialize in equality. It's a common use case to have to take a json document and use it to form a document of another standard WDDX, HTML, etc where ordering needs to be preserved – Andrew Norman Mar 17 '16 at 20:47
  • 4
    @AndrewNorman - If what you said about "need" was really true, then the specification should be and would have been changed. The reality is that it is easy to represent ordering in other ways in JSON. – Stephen C Mar 17 '16 at 22:42
  • 1
    The JSON information model declares JSON to be unordered, but we all know that the JSON serialization string is necessarily ordered. Requirements can apply at the information model level or at the representation level. I have an optimization requirement that is best met by guaranteeing serialization order -- see my comment about real-time testing in the OP. – Joe Lapp Jan 27 '17 at 22:35
  • 2
    JSON only requires that information not be encoded in the order of keys; it's not JSON otherwise. Consistency of serialization is a different issue. Within a single app, consistency can usually be guaranteed by using a common JSON library, but there are exceptions, such as when a single solution spans multiple platforms or frameworks. In these cases, you either have to find a way to deal with the inconsistency (introducing inefficiency), or you find a way to ensure consistency. Both approaches are valid. – Joe Lapp Jan 27 '17 at 22:58
  • 3
    *"JSON only requires that information not be encoded in the order of keys; it's not JSON otherwise."*. I think you wrote that incorrectly. The correct statement is that "JSON does not require that information is encoded in the order of the keys". There is an big difference between these two statements .... – Stephen C Apr 17 '18 at 01:19
  • It really is a simple need... a LOT of common programming tools use JSON for config, and that JSON gets checked into source control. If you need to automatically update those configs in a devops pipeline, you REALLY do not want to have the order inside the JSON files be _randomized_ and re-checked in to source on _every_ pipeline run. This is problem for very standard simple tools such as npm (package.json) or typescript (tsconfig.json). It REALLY isn't some exotic company need. It can of course be argued that JSON was a bad choice of format for these tools... _but here we are!_ Too late! – AnorZaken Oct 28 '22 at 08:07
  • "Too late!" - Yes. In English, there is a saying: "A good workman doesn't blame his tools." (I am referring to JSON as the tool in this context.) As noted previously, JSON can represent ordered things. But you need to use a JSON array to do it. – Stephen C Oct 28 '22 at 11:36
53

It is quite simple to maintain order. I had the same problem with maintaining the order from DB layer to UI Layer.

Open JSONObject.java file. It internally uses HashMap which doesn't maintain the order.

Change it to LinkedHashMap:

    //this.map = new HashMap();
    this.map = new LinkedHashMap();

This worked for me. Let me know in the comments. I suggest the JSON library itself should have another JSONObject class which maintains order, like JSONOrderdObject.java. I am very poor in choosing the names.

Zim-Zam O'Pootertoot
  • 17,888
  • 4
  • 41
  • 69
gary
  • 539
  • 4
  • 2
  • 2
    svn checkout json-simple. modify file org.json.simple.JSONObject, JOSNObject extends LinkedHashMap ... from .. HashMap.., fix the imports and it works for me. v1.1.1. – Marku Jun 29 '13 at 18:20
  • 2
    This is a great one-line solution that I never would have thought to try. Works perfectly, and I didn't have to change any of my other code. +1 – DaaaahWhoosh Sep 11 '15 at 16:34
  • Great fix. You're a hero Sir – Gregory Nowakowski Sep 15 '17 at 13:02
  • didn't work, I added the import, changed it like you said, even tried to do it like this: `this.map = new LinkedHashMap();` still doesn't work. Please help ? – Tarek Aug 14 '18 at 15:23
  • 5
    Haha really? Modifying the JSON library to meet your needs? I can just imagine this going down in company knowledge bases. "Do your mvn clean install, download the jar, find it, decompile it, then replace HashMap with LinkedHashMap". This will work great for multi developer teams (not). – Chris Neve Oct 18 '18 at 07:51
  • Using LinkedHashMap in the library would add essentially no overhead and would break nothing. I don't need things to be in order, but for regression testing, it's a lot easier if the keys come out in the same order they went in. – user3294068 Apr 24 '19 at 21:12
  • How do I override the jar file in my program, the JSONObject class of the jar file that contains a method public JSONObject(Map map)? – Rajashree Jun 21 '21 at 06:16
  • @ChrisNeve I don't see why "number of developers" affects whether you can use a locally forked copy of an existing library in your codebase. – EpicPandaForce Apr 22 '22 at 20:08
27

JSONObject.java takes whatever map you pass. It may be LinkedHashMap or TreeMap and it will take hashmap only when the map is null .

Here is the constructor of JSONObject.java class that will do the checking of map.

 public JSONObject(Map paramMap)
  {
    this.map = (paramMap == null ? new HashMap() : paramMap);
  }

So before building a json object construct LinkedHashMap and then pass it to the constructor like this ,

LinkedHashMap<String, String> jsonOrderedMap = new LinkedHashMap<String, String>();

jsonOrderedMap.put("1","red");
jsonOrderedMap.put("2","blue");
jsonOrderedMap.put("3","green");

JSONObject orderedJson = new JSONObject(jsonOrderedMap);

JSONArray jsonArray = new JSONArray(Arrays.asList(orderedJson));

System.out.println("Ordered JSON Fianl CSV :: "+CDL.toString(jsonArray));

So there is no need to change the JSONObject.java class . Hope it helps somebody .

Ivan Ferić
  • 4,725
  • 11
  • 37
  • 47
Deepak Nagaraj
  • 317
  • 3
  • 7
  • 3
    Good answer, works for normal java, but doesn't work on android. I check the org.json.JSONObject in android, it's a pity that android still use hashmap created internally. It only copy name/value pairs from paramMap to HashMap... :( – 正宗白布鞋 Jun 10 '13 at 18:17
  • I ordered JsonObject but When I try to add that object to an JsonArray it gives me unordered one. I need to put object to array , I need objects of array then I put header to array and sent back. Ex: one object; {CUSTOMER_SECTOR_ID=611, CUSTOMER_NO=0000003204, CUSTOMER_NAME=MARMARİS - KARAS GIDA KARAS TÜKETİM MADDELERİ GIDA LOJ.} I get this If I put two object to array : [{"CUSTOMER_NAME":"SILA GIDA PAZARLAMA ","CUSTOMER_NO":"0000003122","CUSTOMER_SECTOR_ID":"611"},{"CUSTOMER_NAME":"M":"0013114714","CUSTOMER_SECTOR_ID":"611"}] As you see it is wrong. How can I fix it – Sahin Yanlık Apr 30 '14 at 14:37
  • 3
    @Deepak Nagaraj . I've tried your solution but it didn't work, the `JSONObject` is not ordered as my `LinkedHashMap`. Are you usin `org.json` lib ? – Ismail Sen Jul 22 '14 at 09:13
  • 2
    This is not the `org.json` one.. It defines a `HashMap` internally, whatever the `Map` you give to it: @Deepak can you point us to the implementation you used? – Campa Jul 10 '15 at 14:45
  • 9
    This will not work with the `org.json` library. When you construct a new `JSONObject` object, passing a map as an argument, it will always be converted to a `HashMap`. The constructor firstly creates a new map: `this.map = new HashMap();`, and then loop over your map, copying every element to his `HashMap`. – itachi Dec 17 '15 at 12:43
  • 2
    How is this not the top-voted answer? The `JSONObject(Map)` constructor works like a charm (using org.json:json 20080701). Indeed, it may be a little bit of a hack to impose ordering on top of JSON, but there are genuine use cases for this which are not in any way an abuse of the JSON data model; consider serializing JSON to a file in version control, using the order to keep diffs small and meaningful. – joshsh Dec 19 '17 at 02:25
14

Another hacky solution using reflect:

JSONObject json = new JSONObject();
Field map = json.getClass().getDeclaredField("map");
map.setAccessible(true);//because the field is private final...
map.set(json, new LinkedHashMap<>());
map.setAccessible(false);//return flag
fabe
  • 466
  • 5
  • 6
  • 1
    I didn't get your answer – M. Usman Khan May 17 '16 at 13:35
  • 1
    The trick is to modify the class internally to use a LinkedHashMap instead of the default HashMap, making the JSON object have the data in the order you put them in, this is not directly sorted but it worked for me as the data parsed is already sorted. – fabe May 19 '16 at 06:46
  • 1
    looks good, but how to parse Json String AFTER map.set(json, new LinkedHashMap<>()); because Json String is passed in the constructor right? like, new JSONObject(jsonString). – M. Usman Khan May 23 '16 at 13:40
  • Also, this didn't work. there is not field "map", there is a field "nameValuePairs" which is already LinckedHashMap, and it still doesnt work. – M. Usman Khan May 23 '16 at 13:57
  • 1
    What implementation of the JSONObject are you using? I'm using org.json version 20140107 and had to preserve the ordering and thats how it worked for me. – fabe May 24 '16 at 19:45
  • Sorry didn't see your comment about the string constructor, well after modifying the class via reflect you can naturally instantiate the object also via reflect like so: JSONObject.class.getConstructor(String.class).newInstance("your string"); – fabe May 24 '16 at 19:48
13

A more verbose, but broadly applicable solution to this sort of problem is to use a pair of data structures: a list to contain the ordering, and a map to contain the relations.

For Example:

{
    "items":
    [
        {
            "WR":"qwe",
            "QU":"asd",
            "QA":"end",
            "WO":"hasd",
            "NO":"qwer"
        },
    ],
    "itemOrder":
        ["WR", "QU", "QA", "WO", "NO"]
}

You iterate the itemOrder list, and use those to look up the map values. Ordering is preserved, with no kludges.

I have used this method many times.

Robotic Pants
  • 139
  • 1
  • 4
6

Apache Wink has OrderedJSONObject. It keeps the order while parsing the String.

Kirill Rakhman
  • 42,195
  • 18
  • 124
  • 148
4

Just stumbled upon the same problem, I believe the final solution used by the author consisted in using a custom ContainerFactory:

public static Values parseJSONToMap(String msgData) {
    JSONParser parser = new JSONParser();
    ContainerFactory containerFactory = new ContainerFactory(){
        @Override
        public Map createObjectContainer() {
            return new LinkedHashMap();
        }

        @Override
        public List creatArrayContainer() {
            return null;
        }
    };
    try {
        return (Map<String,Object>)parser.parse(msgData, containerFactory);
    } catch (ParseException e) {
        log.warn("Exception parsing JSON string {}", msgData, e);
    }
    return null;
}  

see http://juliusdavies.ca/json-simple-1.1.1-javadocs/org/json/simple/parser/JSONParser.html#parse(java.io.Reader,org.json.simple.parser.ContainerFactory)

Rafael
  • 572
  • 5
  • 9
3

Solved.

I used the JSON.simple library from here https://code.google.com/p/json-simple/ to read the JSON string to keep the order of keys and use JavaCSV library from here http://sourceforge.net/projects/javacsv/ to convert to CSV format.

Hery
  • 7,443
  • 9
  • 36
  • 41
  • I'm surprised that this worked. According to my reading of both the code and comments of the JSONObject class (https://code.google.com/p/json-simple/source/browse/trunk/src/main/java/org/json/simple/JSONObject.java), it doesn't do anything to preserve the order of the keys. – Stephen C Nov 08 '12 at 06:58
  • 1
    I didn't specify the full solution here, but the gist of it is that json-simple provides a factory with which you can specify the data structure used to store json objects. Simply specify to use LinkedHashMap. – Hery Nov 08 '12 at 13:58
  • @Hery,I'm facing the same issue but I couldn't solve it. I use `org.json` to convert `List` to `JSONArray` in order to create a `CSV`, the `CSV` is created but not in the same order as my `List `. I've tried to use the two lib you present here, but I couldn't find the methods to convert to `CSV`.Could you please give more details. – Ismail Sen Jul 22 '14 at 08:52
  • 1
    Can you please explain what you did exactly? – Rajashree Jun 21 '21 at 07:00
  • hello, I can't get the jar anymore since its link is no more working. If anyone can help, please! – zahraa Apr 30 '22 at 23:16
2

In the real world, an application will almost always have java bean or domain that is to be serialized/de-serialized to/from JSON. Its already mentioned that JSON Object specification does not guarantee order and any manipulation to that behavior does not justify the requirement. I had the same scenario in my application where I needed to preserve order just for the sack of readability purpose. I used standard jackson way to serialize my java bean to JSON:

Object object = getObject();  //the source java bean that needs conversion
String jsonString = new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(object);

In order to make the json with an ordered set of elements I just use JSON property annotation in the the Java bean I used for conversion. An example below:

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({"name","phone","city","id"})
public class SampleBean implements Serializable {
    private int id;
    private String name:
    private String city;
    private String phone;

    //...standard getters and setters
}

the getObject() used above:

public SampleBean getObject(){
    SampleBean bean  = new SampleBean();
    bean.setId("100");
    bean.setName("SomeName");
    bean.setCity("SomeCity");
    bean.setPhone("1234567890");
    return bean;
}

The output shows as per Json property order annotation:

{
    name: "SomeName",
    phone: "1234567890",
    city: "SomeCity",
    id: 100
}
Vishal
  • 1,963
  • 2
  • 20
  • 23
1

I know this is solved and the question was asked long time ago, but as I'm dealing with a similar problem, I would like to give a totally different approach to this:

For arrays it says "An array is an ordered collection of values." at http://www.json.org/ - but objects ("An object is an unordered set of name/value pairs.") aren't ordered.

I wonder why that object is in an array - that implies an order that's not there.

{
"items":
[
    {
        "WR":"qwe",
        "QU":"asd",
        "QA":"end",
        "WO":"hasd",
        "NO":"qwer"
    },
]
}

So a solution would be to put the keys in a "real" array and add the data as objects to each key like this:

{
"items":
[
    {"WR": {"data": "qwe"}},
    {"QU": {"data": "asd"}},
    {"QA": {"data": "end"}},
    {"WO": {"data": "hasd"}},
    {"NO": {"data": "qwer"}}
]
}

So this is an approach that tries to rethink the original modelling and its intent. But I haven't tested (and I wonder) if all involved tools would preserve the order of that original JSON array.

mickeymoon
  • 4,820
  • 5
  • 31
  • 56
cslotty
  • 1,696
  • 20
  • 28
  • 1
    this doesn't let me make a lookup on the key. – mickeymoon Jan 28 '15 at 06:44
  • Then what do you want - a hash or something ordered!? If you want to combine both, then create both and have one of those structures index the other one.... otherwise this seems to be more of a design problem, or mixing interests. – cslotty Jan 28 '15 at 13:17
  • 1
    it's not about mixing interests, it is a fairly plausible use case, which in languages like Java is handled by constructs like LinkedHashMap, an ordered map which preserves the insertion order. Then what do I want, I want both to be able to iterate on the keys in the defined order and make a quick lookup on the keys as well. I think the answer by @Robotic Pants would work pretty much, although it is a bit hackish. – mickeymoon Jan 29 '15 at 08:16
  • That's true, mickeymoon, I was about to say that! But in JSON this doesn't exist, does it? Then you would have to involve languages / mechanisms, that do provide you with such a thing. – cslotty Jan 30 '15 at 13:51
1

Underscore-java keeps orders for elements while reading json.

String json = "{\n"
      + "    \"items\":\n"
      + "    [\n"
      + "        {\n"
      + "            \"WR\":\"qwe\",\n"
      + "            \"QU\":\"asd\",\n"
      + "            \"QA\":\"end\",\n"
      + "            \"WO\":\"hasd\",\n"
      + "            \"NO\":\"qwer\"\n"
      + "        }\n"
      + "    ]\n"
      + "}";
System.out.println(U.fromJson(json));

// {items=[{WR=qwe, QU=asd, QA=end, WO=hasd, NO=qwer}]}
Valentyn Kolesnikov
  • 2,029
  • 1
  • 24
  • 31
0

patchFor(answer @gary) :

$ git diff JSONObject.java                                                         
diff --git a/JSONObject.java b/JSONObject.java
index e28c9cd..e12b7a0 100755
--- a/JSONObject.java
+++ b/JSONObject.java
@@ -32,7 +32,7 @@ import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.Collection;
 import java.util.Enumeration;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
@@ -152,7 +152,9 @@ public class JSONObject {
      * Construct an empty JSONObject.
      */
     public JSONObject() {
-        this.map = new HashMap<String, Object>();
+//      this.map = new HashMap<String, Object>();
+        // I want to keep order of the given data:
+        this.map = new LinkedHashMap<String, Object>();
     }

     /**
@@ -243,7 +245,7 @@ public class JSONObject {
      * @throws JSONException
      */
     public JSONObject(Map<String, Object> map) {
-        this.map = new HashMap<String, Object>();
+        this.map = new LinkedHashMap<String, Object>();
         if (map != null) {
             Iterator<Entry<String, Object>> i = map.entrySet().iterator();
             while (i.hasNext()) {
Campa
  • 4,267
  • 3
  • 37
  • 42
0

You can use the following code to do custom ORDERED serialization and deserialization of JSON Array (This example assumes you are ordering Strings but can be applied to all types):

Serialization

JSONArray params = new JSONArray();
int paramIndex = 0;

for (String currParam : mParams)
{
    JSONObject paramObject = new JSONObject();
    paramObject.put("index", paramIndex);
    paramObject.put("value", currParam);

    params.put(paramObject);
    ++paramIndex;
}

json.put("orderedArray", params);

Deserialization

JSONArray paramsJsonArray = json.optJSONArray("orderedArray");
if (null != paramsJsonArray)
{
    ArrayList<String> paramsArr = new ArrayList<>();
    for (int i = 0; i < paramsJsonArray.length(); i++)
    {
        JSONObject param = paramsJsonArray.optJSONObject(i);
        if (null != param)
        {
            int paramIndex = param.optInt("index", -1);
            String paramValue = param.optString("value", null);

            if (paramIndex > -1 && null != paramValue)
            {
                paramsArr.add(paramIndex, paramValue);
            }
        }
    }
}
Muzikant
  • 8,070
  • 5
  • 54
  • 88
0

Your example:

{
    "items":
    [
        {
            "WR":"qwe",
            "QU":"asd",
            "QA":"end",
            "WO":"hasd",
            "NO":"qwer"
        },
        ...
    ]
}

add an element "itemorder"

{
    "items":
    [
        {
            "WR":"qwe",
            "QU":"asd",
            "QA":"end",
            "WO":"hasd",
            "NO":"qwer"
        },
        ...
    ],
    "itemorder":["WR","QU","QA","WO","NO"]
}

This code generates the desired output without the column title line:

JSONObject output = new JSONObject(json);
JSONArray docs = output.getJSONArray("data");
JSONArray names = output.getJSONArray("itemOrder");
String csv = CDL.toString(names,docs);
Adriano
  • 259
  • 3
  • 5
0

instead of using jsonObject try using CsvSchema its way easier and directly converts object to csv

CsvSchema schema = csvMapper.schemaFor(MyClass.class).withHeader();
        csvMapper.writer(schema).writeValueAsString(myClassList);

and it mentains the order id your pojo has @JsonPropertyOrder in it

rahul
  • 880
  • 3
  • 14
  • 25
0

You can use

toString(JSONArray names, JSONArray ja)

It Produces a comma delimited text from a JSONArray of JSONObjects using a provided list of names in the same order as json array .

Refer : https://stleary.github.io/JSON-java/org/json/CDL.html#toString-org.json.JSONArray-org.json.JSONArray-

swarnim gupta
  • 213
  • 1
  • 5
-1

The most safe way is probably overriding keys method that is used to generate output:

new JSONObject(){
  @Override
  public Iterator keys(){
    TreeSet<Object> sortedKeys = new TreeSet<Object>();
    Iterator keys = super.keys();
    while(keys.hasNext()){
      sortedKeys.add(keys.next());
    }
    return sortedKeys.iterator();
  }
};
Kardigen
  • 7
  • 1
  • 1
    This doesn't solve the stated problem. It causes the keys to be sorted ... but the question asks for the insertion order to be preserved. – Stephen C Sep 16 '15 at 22:23
-1

Tested the wink solution, and working fine:

@Test
public void testJSONObject() {
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("bbb", "xxx");
    jsonObject.put("ccc", "xxx");
    jsonObject.put("aaa", "xxx");
    jsonObject.put("xxx", "xxx");
    System.out.println(jsonObject.toString());
    assertTrue(jsonObject.toString().startsWith("{\"xxx\":"));
}

@Test
public void testWinkJSONObject() throws JSONException {
    org.apache.wink.json4j.JSONObject jsonObject = new OrderedJSONObject();
    jsonObject.put("bbb", "xxx");
    jsonObject.put("ccc", "xxx");
    jsonObject.put("aaa", "xxx");
    jsonObject.put("xxx", "xxx");
    assertEquals("{\"bbb\":\"xxx\",\"ccc\":\"xxx\",\"aaa\":\"xxx\",\"xxx\":\"xxx\"}", jsonObject.toString());
}
jgpelaez
  • 11
  • 1