Forums

Home » Liferay Portal » English » 3. Development

Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
Michael Poznecki
JSONObject comes out in bad order
March 4, 2010 10:37 AM
Answer

Michael Poznecki

Rank: Expert

Posts: 301

Join Date: December 10, 2008

Recent Posts

Hello all,

I have:
 1
 2JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
 3
 4jsonObject.put("a", "1");
 5jsonObject.put("b", "2");
 6jsonObject.put("c", "3");
 7jsonObject.put("d", "4");
 8
 9...


but when I spit out the results I have

[{"d":"4","b":"2","c":"3","a":"1"}]


How can I get this to come out in the right order without sorting it after?
Amos Fong
RE: JSONObject comes out in bad order
March 4, 2010 10:52 AM
Answer

Amos Fong

LIFERAY STAFF

Rank: Liferay Legend

Posts: 1817

Join Date: October 7, 2008

Recent Posts

From http://groups.google.com/group/android-developers/browse_thread/thread/0afcf8622cfe8905

Your code is incorrect if you're relying on ordering. I'll get to
that, but first some background which may come in handy:

HashMaps are unordered. If you want to preserve order, there's
LinkedHashMap, which retains the order, so when you iterate over the
map, you get the order in which they were inserted. And there's
TreeMap, which will enforce a sorting order for you, independent of
what order they're supplied in.

Unfortunately, that doesn't help you, since the JSONObject
implementation uses HashMap.
But you can iterate over the keys you get back with JSONObject.keys(),
and store the keys in a TreeSet, sorted according to your preferences,
or in an ArrayList, and call Collections.sort() on it, and then
iterate over the result. That's a simple, robust solution, if the
client knows what order the keys should be in.

But that doesn't give you the original order. The options I see there
are:

* A modified version of the JSON code. I don't recommend it,
especially not to deviate from the standard, but if you have no
control over what you're being sent, this may be your only
alternative. Just take the current code, and whenever it does 'new
HashTable()', do 'new LinkedHashTable()'.

* Modify your protocol to pass the desired key order explicitly (as
the value of another key on the object, or on some single larger
object, etc.). Call JSONObject.keys(), and iterate over that. This is
the most robust solution, but requires server-side cooperation, and
increases the payload size a bit.

I may be slightly misremembering, but if I recall correctly,
preservation of the key ordering was NOT part of the Javascript/
ECMAscript standards -- but was so widely implemented and relied on
that in the most recent round they made it part of the standard-to-be.
HOWEVER, JSON is *NOT* Javascript, it is a data interchange language.
From the JSON web site:

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

So this is not a JSON bug; it is behaving as expected, for
compatibility across a wide range of languages. So you'll either have
to change your protocol, or accommodate your deviation from the
standard.