Keep the order of the JSON keys during JSON conversion to CSV
Asked Answered
C

18

94

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?

Carmacarmack answered 23/12, 2010 at 3:40 Comment(5)
Dictionaries are unsorted. I don't even think JSON guarantees order.Hynes
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 :(Carmacarmack
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.Rectus
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.Zavala
write your own code to convert JSON to a specificaly ordered CSV file, that way you respect what both formats are supposed to be.String
C
4

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.

Carmacarmack answered 23/12, 2010 at 6:29 Comment(5)
I'm surprised that this worked. According to my reading of both the code and comments of the JSONObject class (code.google.com/p/json-simple/source/browse/trunk/src/main/java/…), it doesn't do anything to preserve the order of the keys.Rabbitry
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.Carmacarmack
@Hery,I'm facing the same issue but I couldn't solve it. I use org.json to convert List<LinkedHahMap> 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.Sidnee
Can you please explain what you did exactly?Durazzo
hello, I can't get the jar anymore since its link is no more working. If anyone can help, please!Feller
R
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.

Rabbitry answered 23/12, 2010 at 4:28 Comment(14)
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...Carmacarmack
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 hahaCarmacarmack
@StephenC : Nice answer. I am struggling with the same problem and its creating duplicity in my paginated ListView. What the heck !!! No solutions ?Cabalism
@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.Rabbitry
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 preservedCorcoran
@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.Rabbitry
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.Zavala
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.Zavala
"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 ....Rabbitry
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!Mediant
"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.Rabbitry
@StephenC Stumbled across this thread ... does key order matter to a computer? No. Does it matter to documentation, UI, a human, etc. Yup, it sure does. Surely you have to agree that "username" and "password" belong together rather then one at the top and one at the bottom? There's a reason why Spring, etc. serialize out in order. Some implementations PURPOSELY make then unordered (like org.json) because they are "spec nazis". That's cool. Gson preserves order because they know that's the most common use case. So bye bye org.json :).Laue
"Surely you have to agree that "username" and "password" belong together rather then one at the top and one at the bottom?" - No I don't. In fact, as a user (of a typical API) I probably don't care about the order of the parameters. But that that's not really the issue. And computers do what they are told. The real issue is programmers and the software that they write and that they depend.Rabbitry
"Some implementations PURPOSELY make then unordered (like org.json) because they are "spec nazis"." - Did you ask the implementors why? Did they >say< that? Other possible explanations are that a JSON stack could be faster, smaller, simpler if you don't need to preserve order end-to-end. And bear in mind that when you use JSON in a public API, there are (at least) two JSON implementations involved; on the client side and the server side. And possibly multiple programming languages. For many folks "just use GSON everywhere" is not a solution ... cos they don't control "everywhere".Rabbitry
F
52

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.

Fruity answered 2/11, 2011 at 14:5 Comment(8)
svn checkout json-simple. modify file org.json.simple.JSONObject, <code>JOSNObject extends LinkedHashMap ...</code> from <code>.. HashMap..</code>, fix the imports and it works for me. v1.1.1.Bolinger
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. +1Fulgurating
Great fix. You're a hero SirEffeminate
didn't work, I added the import, changed it like you said, even tried to do it like this: this.map = new LinkedHashMap<String, Object>(); still doesn't work. Please help ?Robinette
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).Camarillo
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.Appeasement
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)?Durazzo
@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.Hounding
T
29

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 .

Tenderfoot answered 24/1, 2013 at 8:13 Comment(6)
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... :(Pronucleus
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 itShalandashale
@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 ?Sidnee
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?Galoshes
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<String, Object>();, and then loop over your map, copying every element to his HashMap.Tailback
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.Reckless
G
16

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
Ge answered 4/3, 2016 at 13:20 Comment(6)
I didn't get your answerBelabor
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.Ge
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).Belabor
Also, this didn't work. there is not field "map", there is a field "nameValuePairs" which is already LinckedHashMap, and it still doesnt work.Belabor
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.Ge
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");Ge
P
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.

Periwig answered 11/6, 2014 at 18:46 Comment(1)
This becomes complicated if your map isn't just simple key-value pairs...Cretic
W
6

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

Whitelaw answered 21/11, 2013 at 19:41 Comment(0)
C
4

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.

Carmacarmack answered 23/12, 2010 at 6:29 Comment(5)
I'm surprised that this worked. According to my reading of both the code and comments of the JSONObject class (code.google.com/p/json-simple/source/browse/trunk/src/main/java/…), it doesn't do anything to preserve the order of the keys.Rabbitry
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.Carmacarmack
@Hery,I'm facing the same issue but I couldn't solve it. I use org.json to convert List<LinkedHahMap> 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.Sidnee
Can you please explain what you did exactly?Durazzo
hello, I can't get the jar anymore since its link is no more working. If anyone can help, please!Feller
G
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)

Gramps answered 4/12, 2014 at 12:7 Comment(1)
really very good and practical solution. How about writing method local anonymous inner class for containerFactory?Eulogize
S
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
}
Selfconceit answered 9/5, 2017 at 17:56 Comment(0)
M
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.

Mongoose answered 19/1, 2015 at 15:14 Comment(4)
this doesn't let me make a lookup on the key.Brooklyn
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.Mongoose
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.Brooklyn
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.Mongoose
P
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}]}
Paperweight answered 24/11, 2019 at 18:58 Comment(0)
G
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()) {
Galoshes answered 10/7, 2015 at 14:51 Comment(0)
T
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);
            }
        }
    }
}
Tragic answered 19/1, 2016 at 17:11 Comment(0)
S
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);
Simpatico answered 10/6, 2016 at 19:32 Comment(1)
This removed the header of the CSV, now I have the rows ordered but without headerConnected
L
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

Lina answered 6/3, 2019 at 4:50 Comment(0)
P
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-

Pervious answered 8/6, 2021 at 8:28 Comment(0)
O
-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();
  }
};
Ohara answered 4/6, 2015 at 11:15 Comment(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.Rabbitry
C
-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());
}
Carbon answered 5/8, 2015 at 10:11 Comment(2)
Maven dependency: <dependency> <groupId>org.apache.wink</groupId> <artifactId>wink-json4j</artifactId> <version>1.4</version> </dependency>Carbon
Same answer as @cypressious ... posted 2 years earlier. And the example adds no real value.Rabbitry

© 2022 - 2024 — McMap. All rights reserved.