6

Which would be the best way to do it? Right now, I convert my JSONArray to an ArrayList of a custom class, use Collections.shuffle() to perform the action, and convert back to JSONArray, which seems to be too much overhead.

The answer may be just to implement a Fisher-Yates shuffle for it, but my guess is that this may be already done so I would like to avoid reinventing the wheel. I looked at the standard JSON api and Google's Gson but they don't seem to have any implementation.

There are also simple options for a standard array in this question that could be easily ported to java, but I would gladly hear your input. I am amazed that the query http://www.google.com/search?q=java+shuffle+jsonarray did not flood me with methods.

Community
  • 1
  • 1
Aleadam
  • 40,203
  • 9
  • 86
  • 108
  • 1
    "seems to be too much overhead" - have you profiled it, or is this just a guess? If it's just a guess, profile it and then determine if it's really an issue at all. – corsiKa Apr 03 '11 at 17:17
  • I understand what you say, but for now the arrays are very small, so it is not really noticeable, but I want to make sure the code remains scalable for when the number of arrays (and size) increase. – Aleadam Apr 03 '11 at 18:30

3 Answers3

15

Sorry for posting an answer to my own question, but right now, since there was no out-of-the-box quick solution, I'm implementing my own static shuffle function based on the code from this post: Random shuffling of an array . Still looking forward to hear about the best implementation. This is what I did:

public static JSONArray shuffleJsonArray (JSONArray array) throws JSONException {
    // Implementing Fisher–Yates shuffle
        Random rnd = new Random();
        for (int i = array.length() - 1; i >= 0; i--)
        {
          int j = rnd.nextInt(i + 1);
          // Simple swap
          Object object = array.get(j);
          array.put(j, array.get(i));
          array.put(i, object);
        }
    return array;
}
Community
  • 1
  • 1
Aleadam
  • 40,203
  • 9
  • 86
  • 108
2

Your method works great, but don't forget to:

rnd.setSeed(System.currentTimeMillis());

so that the results are unique each time.

Sorry for the new answer, I don't have enough rep to post a comment :/

Nate
  • 55
  • 6
1

Use a JSON library that doesn't require you to convert to some kind of JSON data structure when the language already has perfectly good List and Map interfaces built in.

http://code.google.com/p/prebake/source/browse/trunk/code/src/org/prebake/js/JsonSink.java and http://code.google.com/p/prebake/source/browse/trunk/code/src/org/prebake/js/JsonSource.java for example.

Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
  • +1 Thanks for the links. I will look into them further, but there doesn't seem to be much documentation about it. – Aleadam Apr 03 '11 at 18:33