sort fields in ReflectionToStringBuilder for deterministic order (#481)

diff --git a/src/main/java/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java b/src/main/java/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java
index 392cdb5..aeed52e 100644
--- a/src/main/java/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java
+++ b/src/main/java/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java
@@ -23,6 +23,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Comparator;
 import java.util.List;
 
 import org.apache.commons.lang3.ArrayUtils;
@@ -639,7 +640,9 @@
             this.reflectionAppendArray(this.getObject());
             return;
         }
+        // The elements in the returned array are not sorted and are not in any particular order.
         final Field[] fields = clazz.getDeclaredFields();
+        Arrays.sort(fields, Comparator.comparing(Field::getName));
         AccessibleObject.setAccessible(fields, true);
         for (final Field field : fields) {
             final String fieldName = field.getName();
diff --git a/src/test/java/org/apache/commons/lang3/builder/MultilineRecursiveToStringStyleTest.java b/src/test/java/org/apache/commons/lang3/builder/MultilineRecursiveToStringStyleTest.java
index 4eb1db4..4c302b8 100644
--- a/src/test/java/org/apache/commons/lang3/builder/MultilineRecursiveToStringStyleTest.java
+++ b/src/test/java/org/apache/commons/lang3/builder/MultilineRecursiveToStringStyleTest.java
@@ -46,12 +46,12 @@
         final Bank bank = new Bank("ASF Bank");
         customer.bank = bank;
         final String exp = getClassPrefix(customer) + "[" + BR
-                   + "  name=Douglas Adams," + BR
+                   + "  accounts=<null>," + BR
                    + "  bank=" + getClassPrefix(bank) + "[" + BR
                    + "    name=ASF Bank" + BR
                    + "  ]," + BR
-                   + "  accounts=<null>" + BR
-                   + "]";
+                   + "  name=Douglas Adams" + BR
+                + "]";
         assertEquals(exp, toString(customer));
     }
 
@@ -84,8 +84,8 @@
         final String exp = getClassPrefix(wa) + "[" + BR
                    + "  boolArray=<null>," + BR
                    + "  charArray=<null>," + BR
-                   + "  intArray=<null>," + BR
                    + "  doubleArray=<null>," + BR
+                   + "  intArray=<null>," + BR
                    + "  longArray=<null>," + BR
                    + "  stringArray=<null>" + BR
                    + "]";
@@ -103,8 +103,8 @@
                    + "    true" + BR
                    + "  }," + BR
                    + "  charArray=<null>," + BR
-                   + "  intArray=<null>," + BR
                    + "  doubleArray=<null>," + BR
+                   + "  intArray=<null>," + BR
                    + "  longArray=<null>," + BR
                    + "  stringArray=<null>" + BR
                    + "]";
@@ -121,8 +121,8 @@
                    + "    a," + BR
                    + "    A" + BR
                    + "  }," + BR
-                   + "  intArray=<null>," + BR
                    + "  doubleArray=<null>," + BR
+                   + "  intArray=<null>," + BR
                    + "  longArray=<null>," + BR
                    + "  stringArray=<null>" + BR
                    + "]";
@@ -136,11 +136,11 @@
         final String exp = getClassPrefix(wa) + "[" + BR
                    + "  boolArray=<null>," + BR
                    + "  charArray=<null>," + BR
+                   + "  doubleArray=<null>," + BR
                    + "  intArray={" + BR
                    + "    1," + BR
                    + "    2" + BR
                    + "  }," + BR
-                   + "  doubleArray=<null>," + BR
                    + "  longArray=<null>," + BR
                    + "  stringArray=<null>" + BR
                    + "]";
@@ -154,11 +154,11 @@
         final String exp = getClassPrefix(wa) + "[" + BR
                    + "  boolArray=<null>," + BR
                    + "  charArray=<null>," + BR
-                   + "  intArray=<null>," + BR
                    + "  doubleArray={" + BR
                    + "    1.0," + BR
                    + "    2.0" + BR
                    + "  }," + BR
+                   + "  intArray=<null>," + BR
                    + "  longArray=<null>," + BR
                    + "  stringArray=<null>" + BR
                    + "]";
@@ -172,8 +172,8 @@
         final String exp = getClassPrefix(wa) + "[" + BR
                    + "  boolArray=<null>," + BR
                    + "  charArray=<null>," + BR
-                   + "  intArray=<null>," + BR
                    + "  doubleArray=<null>," + BR
+                   + "  intArray=<null>," + BR
                    + "  longArray={" + BR
                    + "    1," + BR
                    + "    2" + BR
@@ -190,8 +190,8 @@
         final String exp = getClassPrefix(wa) + "[" + BR
                    + "  boolArray=<null>," + BR
                    + "  charArray=<null>," + BR
-                   + "  intArray=<null>," + BR
                    + "  doubleArray=<null>," + BR
+                   + "  intArray=<null>," + BR
                    + "  longArray=<null>," + BR
                    + "  stringArray={" + BR
                    + "    a," + BR
@@ -226,8 +226,8 @@
     static class WithArrays {
         boolean[] boolArray;
         char[] charArray;
-        int[] intArray;
         double[] doubleArray;
+        int[] intArray;
         long[] longArray;
         String[] stringArray;
     }
diff --git a/src/test/java/org/apache/commons/lang3/builder/RecursiveToStringStyleTest.java b/src/test/java/org/apache/commons/lang3/builder/RecursiveToStringStyleTest.java
index 9ef82f1..5a438dd 100644
--- a/src/test/java/org/apache/commons/lang3/builder/RecursiveToStringStyleTest.java
+++ b/src/test/java/org/apache/commons/lang3/builder/RecursiveToStringStyleTest.java
@@ -91,7 +91,7 @@
         p.job.title = "Manager";
         final String pBaseStr = p.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(p));
         final String pJobStr  = p.job.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(p.job));
-        assertEquals(pBaseStr + "[name=John Doe,age=33,smoker=false,job=" + pJobStr + "[title=Manager]]",
+        assertEquals(pBaseStr + "[age=33,job=" + pJobStr + "[title=Manager],name=John Doe,smoker=false]",
                      new ReflectionToStringBuilder(p, new RecursiveToStringStyle()).toString());
     }
 
diff --git a/src/test/java/org/apache/commons/lang3/builder/ToStringBuilderTest.java b/src/test/java/org/apache/commons/lang3/builder/ToStringBuilderTest.java
index 72ce965..b5fead2 100644
--- a/src/test/java/org/apache/commons/lang3/builder/ToStringBuilderTest.java
+++ b/src/test/java/org/apache/commons/lang3/builder/ToStringBuilderTest.java
@@ -543,7 +543,7 @@
     @Test
     public void testSelfInstanceTwoVarsReflectionObjectCycle() {
         final SelfInstanceTwoVarsReflectionTestFixture test = new SelfInstanceTwoVarsReflectionTestFixture();
-        assertEquals(this.toBaseString(test) + "[typeIsSelf=" + this.toBaseString(test) + ",otherType=" + test.getOtherType().toString() + "]", test.toString());
+        assertEquals(this.toBaseString(test) + "[otherType=" + test.getOtherType().toString() + ",typeIsSelf=" + this.toBaseString(test)  + "]", test.toString());
     }
 
 
@@ -1140,16 +1140,16 @@
     public void testSimpleReflectionStatics() {
         final SimpleReflectionStaticFieldsFixture instance1 = new SimpleReflectionStaticFieldsFixture();
         assertEquals(
-            this.toBaseString(instance1) + "[staticString=staticString,staticInt=12345]",
+            this.toBaseString(instance1) + "[staticInt=12345,staticString=staticString]",
             ReflectionToStringBuilder.toString(instance1, null, false, true, SimpleReflectionStaticFieldsFixture.class));
         assertEquals(
-            this.toBaseString(instance1) + "[staticString=staticString,staticInt=12345]",
+            this.toBaseString(instance1) + "[staticInt=12345,staticString=staticString]",
             ReflectionToStringBuilder.toString(instance1, null, true, true, SimpleReflectionStaticFieldsFixture.class));
         assertEquals(
-            this.toBaseString(instance1) + "[staticString=staticString,staticInt=12345]",
+            this.toBaseString(instance1) + "[staticInt=12345,staticString=staticString]",
             this.toStringWithStatics(instance1, null, SimpleReflectionStaticFieldsFixture.class));
         assertEquals(
-            this.toBaseString(instance1) + "[staticString=staticString,staticInt=12345]",
+            this.toBaseString(instance1) + "[staticInt=12345,staticString=staticString]",
             this.toStringWithStatics(instance1, null, SimpleReflectionStaticFieldsFixture.class));
     }
 
@@ -1160,16 +1160,16 @@
     public void testReflectionStatics() {
         final ReflectionStaticFieldsFixture instance1 = new ReflectionStaticFieldsFixture();
         assertEquals(
-            this.toBaseString(instance1) + "[staticString=staticString,staticInt=12345,instanceString=instanceString,instanceInt=67890]",
+            this.toBaseString(instance1) + "[instanceInt=67890,instanceString=instanceString,staticInt=12345,staticString=staticString]",
             ReflectionToStringBuilder.toString(instance1, null, false, true, ReflectionStaticFieldsFixture.class));
         assertEquals(
-            this.toBaseString(instance1) + "[staticString=staticString,staticInt=12345,staticTransientString=staticTransientString,staticTransientInt=54321,instanceString=instanceString,instanceInt=67890,transientString=transientString,transientInt=98765]",
+            this.toBaseString(instance1) + "[instanceInt=67890,instanceString=instanceString,staticInt=12345,staticString=staticString,staticTransientInt=54321,staticTransientString=staticTransientString,transientInt=98765,transientString=transientString]",
             ReflectionToStringBuilder.toString(instance1, null, true, true, ReflectionStaticFieldsFixture.class));
         assertEquals(
-            this.toBaseString(instance1) + "[staticString=staticString,staticInt=12345,instanceString=instanceString,instanceInt=67890]",
+            this.toBaseString(instance1) + "[instanceInt=67890,instanceString=instanceString,staticInt=12345,staticString=staticString]",
             this.toStringWithStatics(instance1, null, ReflectionStaticFieldsFixture.class));
         assertEquals(
-            this.toBaseString(instance1) + "[staticString=staticString,staticInt=12345,instanceString=instanceString,instanceInt=67890]",
+            this.toBaseString(instance1) + "[instanceInt=67890,instanceString=instanceString,staticInt=12345,staticString=staticString]",
             this.toStringWithStatics(instance1, null, ReflectionStaticFieldsFixture.class));
     }
 
@@ -1180,16 +1180,16 @@
     public void testInheritedReflectionStatics() {
         final InheritedReflectionStaticFieldsFixture instance1 = new InheritedReflectionStaticFieldsFixture();
         assertEquals(
-            this.toBaseString(instance1) + "[staticString2=staticString2,staticInt2=67890]",
+            this.toBaseString(instance1) + "[staticInt2=67890,staticString2=staticString2]",
             ReflectionToStringBuilder.toString(instance1, null, false, true, InheritedReflectionStaticFieldsFixture.class));
         assertEquals(
-            this.toBaseString(instance1) + "[staticString2=staticString2,staticInt2=67890,staticString=staticString,staticInt=12345]",
+            this.toBaseString(instance1) + "[staticInt2=67890,staticString2=staticString2,staticInt=12345,staticString=staticString]",
             ReflectionToStringBuilder.toString(instance1, null, false, true, SimpleReflectionStaticFieldsFixture.class));
         assertEquals(
-            this.toBaseString(instance1) + "[staticString2=staticString2,staticInt2=67890,staticString=staticString,staticInt=12345]",
+            this.toBaseString(instance1) + "[staticInt2=67890,staticString2=staticString2,staticInt=12345,staticString=staticString]",
             this.toStringWithStatics(instance1, null, SimpleReflectionStaticFieldsFixture.class));
         assertEquals(
-            this.toBaseString(instance1) + "[staticString2=staticString2,staticInt2=67890,staticString=staticString,staticInt=12345]",
+            this.toBaseString(instance1) + "[staticInt2=67890,staticString2=staticString2,staticInt=12345,staticString=staticString]",
             this.toStringWithStatics(instance1, null, SimpleReflectionStaticFieldsFixture.class));
     }