@@ -245,14 +245,14 @@ public JSONObject(JSONTokener x) throws JSONException {
245245 /**
246246 * Construct a JSONObject from a Map.
247247 *
248- * @param map
248+ * @param m
249249 * A map object that can be used to initialize the contents of
250250 * the JSONObject.
251251 */
252- public JSONObject (Map <?, ?> map ) {
252+ public JSONObject (Map <?, ?> m ) {
253253 this .map = new HashMap <String , Object >();
254- if (map != null ) {
255- for (final Entry <?, ?> e : map .entrySet ()) {
254+ if (m != null ) {
255+ for (final Entry <?, ?> e : m .entrySet ()) {
256256 final Object value = e .getValue ();
257257 if (value != null ) {
258258 this .map .put (String .valueOf (e .getKey ()), wrap (value ));
@@ -729,14 +729,7 @@ public static String[] getNames(JSONObject jo) {
729729 if (length == 0 ) {
730730 return null ;
731731 }
732- Iterator <String > iterator = jo .keys ();
733- String [] names = new String [length ];
734- int i = 0 ;
735- while (iterator .hasNext ()) {
736- names [i ] = iterator .next ();
737- i ++;
738- }
739- return names ;
732+ return jo .keySet ().toArray (new String [length ]);
740733 }
741734
742735 /**
@@ -837,23 +830,45 @@ public boolean isNull(String key) {
837830 }
838831
839832 /**
840- * Get an enumeration of the keys of the JSONObject.
833+ * Get an enumeration of the keys of the JSONObject. Modifying this key Set will also
834+ * modify the JSONObject. Use with caution.
841835 *
836+ * @see Set#iterator()
837+ *
842838 * @return An iterator of the keys.
843839 */
844840 public Iterator <String > keys () {
845841 return this .keySet ().iterator ();
846842 }
847843
848844 /**
849- * Get a set of keys of the JSONObject.
845+ * Get a set of keys of the JSONObject. Modifying this key Set will also modify the
846+ * JSONObject. Use with caution.
847+ *
848+ * @see Map#keySet()
850849 *
851850 * @return A keySet.
852851 */
853852 public Set <String > keySet () {
854853 return this .map .keySet ();
855854 }
856855
856+ /**
857+ * Get a set of entries of the JSONObject. These are raw values and may not
858+ * match what is returned by the JSONObject get* and opt* functions. Modifying
859+ * the returned EntrySet or the Entry objects contained therein will modify the
860+ * backing JSONObject. This does not return a clone or a read-only view.
861+ *
862+ * Use with caution.
863+ *
864+ * @see Map#entrySet()
865+ *
866+ * @return A keySet.
867+ */
868+ protected Set <Entry <String , Object >> entrySet () {
869+ return this .map .entrySet ();
870+ }
871+
857872 /**
858873 * Get the number of keys stored in the JSONObject.
859874 *
@@ -871,12 +886,10 @@ public int length() {
871886 * is empty.
872887 */
873888 public JSONArray names () {
874- JSONArray ja = new JSONArray ();
875- Iterator <String > keys = this .keys ();
876- while (keys .hasNext ()) {
877- ja .put (keys .next ());
878- }
879- return ja .length () == 0 ? null : ja ;
889+ if (this .map .isEmpty ()) {
890+ return null ;
891+ }
892+ return new JSONArray (this .map .keySet ());
880893 }
881894
882895 /**
@@ -1762,15 +1775,19 @@ public boolean similar(Object other) {
17621775 if (!(other instanceof JSONObject )) {
17631776 return false ;
17641777 }
1765- Set <String > set = this .keySet ();
1766- if (!set .equals (((JSONObject )other ).keySet ())) {
1778+ if (!this .keySet ().equals (((JSONObject )other ).keySet ())) {
17671779 return false ;
17681780 }
1769- Iterator <String > iterator = set .iterator ();
1770- while (iterator .hasNext ()) {
1771- String name = iterator .next ();
1772- Object valueThis = this .get (name );
1781+ for (final Entry <String ,?> entry : this .entrySet ()) {
1782+ String name = entry .getKey ();
1783+ Object valueThis = entry .getValue ();
17731784 Object valueOther = ((JSONObject )other ).get (name );
1785+ if (valueThis == valueOther ) {
1786+ return true ;
1787+ }
1788+ if (valueThis == null ) {
1789+ return false ;
1790+ }
17741791 if (valueThis instanceof JSONObject ) {
17751792 if (!((JSONObject )valueThis ).similar (valueOther )) {
17761793 return false ;
@@ -2220,34 +2237,32 @@ public Writer write(Writer writer, int indentFactor, int indent)
22202237 try {
22212238 boolean commanate = false ;
22222239 final int length = this .length ();
2223- Iterator <String > keys = this .keys ();
22242240 writer .write ('{' );
22252241
22262242 if (length == 1 ) {
2227- Object key = keys .next ();
2228- writer .write (quote (key . toString ()));
2243+ final Entry < String ,?> entry = this . entrySet (). iterator () .next ();
2244+ writer .write (quote (entry . getKey ()));
22292245 writer .write (':' );
22302246 if (indentFactor > 0 ) {
22312247 writer .write (' ' );
22322248 }
2233- writeValue (writer , this . map . get ( key ), indentFactor , indent );
2249+ writeValue (writer , entry . getValue ( ), indentFactor , indent );
22342250 } else if (length != 0 ) {
22352251 final int newindent = indent + indentFactor ;
2236- while (keys .hasNext ()) {
2237- Object key = keys .next ();
2252+ for (final Entry <String ,?> entry : this .entrySet ()) {
22382253 if (commanate ) {
22392254 writer .write (',' );
22402255 }
22412256 if (indentFactor > 0 ) {
22422257 writer .write ('\n' );
22432258 }
22442259 indent (writer , newindent );
2245- writer .write (quote (key . toString ()));
2260+ writer .write (quote (entry . getKey ()));
22462261 writer .write (':' );
22472262 if (indentFactor > 0 ) {
22482263 writer .write (' ' );
22492264 }
2250- writeValue (writer , this . map . get ( key ), indentFactor , newindent );
2265+ writeValue (writer , entry . getValue ( ), indentFactor , newindent );
22512266 commanate = true ;
22522267 }
22532268 if (indentFactor > 0 ) {
@@ -2273,7 +2288,7 @@ public Writer write(Writer writer, int indentFactor, int indent)
22732288 */
22742289 public Map <String , Object > toMap () {
22752290 Map <String , Object > results = new HashMap <String , Object >();
2276- for (Entry <String , Object > entry : this .map . entrySet ()) {
2291+ for (Entry <String , Object > entry : this .entrySet ()) {
22772292 Object value ;
22782293 if (entry .getValue () == null || NULL .equals (entry .getValue ())) {
22792294 value = null ;
0 commit comments