franslundberg/binson-java

Binson.keySet() does not return the set of field names in correct order

sijohans opened this issue · 2 comments

It seems like the keyset of Strings returned by keySet() does not return the field names in correct order. Or are there any other ways of looping through the fields?

This code reproduces this:

package org.binson;

public class Bug {

    public static void main(String[] args) {

        Binson b = new Binson()
                .put("c", "A")
                .put("i", 20)
                .put("o", "s")
                .put("z", new Binson().put("A", "B").put("ch", new byte[]{0x01,0x02}));
        System.out.println(b.toPrettyJson());


        for (String field : b.keySet()) {
            System.out.println("Field name: " + field);
        }

    }

}

The output from this is:

{
  "c": "A", 
  "i": 20, 
  "o": "s", 
  "z": {
    "A": "B", 
    "ch": "0x0102"
  }
}

Field name: c
Field name: i
Field name: z
Field name: o

I wrote a simple JUnit test case for this:

package org.binson;

import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class KeySetTest {

    @Test
    public void keySetShouldBeOrdered() {
        Binson b = new Binson()
                .put("c", "A")
                .put("i", 20)
                .put("o", "s")
                .put("z", new Binson().put("A", "B").put("ch", new byte[]{0x01,0x02}));

        String fieldNames[] = new String[]{"c","i","o","z"};

        int i = 0;

        for (String field : b.keySet()) {
            assertEquals(field, fieldNames[i]);
            i++;
        }

    }
}

The reason i noticed this is that i have written a code generator that writes C code. I then use this to generate a lot of test cases. I assume this has to do with the HashMap that is used. I see in the JSON output that the set of string is converted to an array and then sorted:

String[] keys = obj.keySet().toArray(EMPTY_STRING_ARRAY);
Arrays.sort(keys, BinsonFieldNameComparator.INSTANCE);

When digging into this, i also see that the interface Output seems like a better approach than mine :)

Perhaps we need a function that returns a List. Java's Set is not ordered.

Closing this issue. Not a bug - wont fix. "Set" is not ordered by definition. The possible enhancement of adding support for getting all the fields in order is another thing; a feature request.