ralfstx / minimal-json

A fast and small JSON parser and writer for Java
MIT License
732 stars 186 forks source link

Sorting #101

Open blongstreth opened 6 years ago

blongstreth commented 6 years ago

Hi: I was trying to figure out an easy way to sort a JsonObject without being too expense but still work with duplicate members. In my adventures, I ended up trying the following things:

  1. Deep copy with sort. I had to do this because JsonObject doesn't have the ability to clear (i.e. no JsonObject.clear method) and reapply the members without being too expensive, I had to copy/clone which is unfortunate.

  2. Next I thought about focusing on just sorting during the write phase. I ended up doing something like this (using Java 8):

public class MyJsonObject extends JsonObject
{
   private final boolean sortable;

   public MyJsonObject(final boolean sortable)
   {
      this.sortable = sortable;
   }

   public MyJsonObject(final boolean sortable, final JsonObject object)
   {
      super(object);
      this.sortable = sortable;
   }

   @Override
   void write(final JsonWriter writer)
         throws IOException
   {
      if (isSortable())
      {
         final List<Member> sortedMembers = new ArrayList<>(size());
         for (final Member member: this)
         {
            sortedMembers.add(member);
         }

         // Sort by member name
         sortedMembers.sort(Comparator.comparing(JsonObject.Member::getName));

         // Write
         writer.writeObjectOpen();
         for (int i = 0; i < sortedMembers.size(); i++)
         {
            final Member member = sortedMembers.get(i);
            if (i > 0)
            {
               writer.writeObjectSeparator();
            }
            writer.writeMemberName(member.getName());
            writer.writeMemberSeparator();
            member.getValue().write(writer);
         }
         writer.writeObjectClose();
      }
      else
      {
         super.write(writer);
      }
   }

   public boolean isSortable()
   {
      return sortable;
   }
}

This is not ideal because the class should not be extended per documentation, write method is package protected, no access to the lists (used the more expensive member iterator) and I had to throw it into the same package namespace.

As a result, I think it would be nice if JsonObject had a clear and a sort method in addition to sort while writing. Just some ideas. Any help would be greatly appreciated. For now, I am working around it somewhat.