diff --git a/JSONArray.java b/JSONArray.java index 54d5183..a402d67 100644 --- a/JSONArray.java +++ b/JSONArray.java @@ -154,8 +154,10 @@ public class JSONArray implements Iterable { * A Collection. */ public JSONArray(Collection collection) { - this.myArrayList = new ArrayList(); - if (collection != null) { + if (collection == null) { + this.myArrayList = new ArrayList(); + } else { + this.myArrayList = new ArrayList(collection.size()); for (Object o: collection){ this.myArrayList.add(JSONObject.wrap(o)); } @@ -172,6 +174,7 @@ public class JSONArray implements Iterable { this(); if (array.getClass().isArray()) { int length = Array.getLength(array); + this.myArrayList.ensureCapacity(length); for (int i = 0; i < length; i += 1) { this.put(JSONObject.wrap(Array.get(array, i))); } @@ -495,7 +498,7 @@ public class JSONArray implements Iterable { * Get the optional object value associated with an index. * * @param index - * The index must be between 0 and length() - 1. + * The index must be between 0 and length() - 1. If not, null is returned. * @return An object value, or null if there is no object at that index. */ public Object opt(int index) { @@ -1150,7 +1153,13 @@ public class JSONArray implements Iterable { } if (index < this.length()) { this.myArrayList.set(index, value); + } else if(index == this.length()){ + // simple append + this.put(value); } else { + // if we are inserting past the length, we want to grow the array all at once + // instead of incrementally. + this.myArrayList.ensureCapacity(index + 1); while (index != this.length()) { this.put(JSONObject.NULL); } @@ -1302,7 +1311,7 @@ public class JSONArray implements Iterable { if (names == null || names.length() == 0 || this.length() == 0) { return null; } - JSONObject jo = new JSONObject(); + JSONObject jo = new JSONObject(names.length()); for (int i = 0; i < names.length(); i += 1) { jo.put(names.getString(i), this.opt(i)); } diff --git a/JSONObject.java b/JSONObject.java index 060a196..8ad7864 100644 --- a/JSONObject.java +++ b/JSONObject.java @@ -184,7 +184,7 @@ public class JSONObject { * An array of strings. */ public JSONObject(JSONObject jo, String[] names) { - this(); + this(names.length); for (int i = 0; i < names.length; i += 1) { try { this.putOnce(names[i], jo.opt(names[i])); @@ -256,8 +256,10 @@ public class JSONObject { * the JSONObject. */ public JSONObject(Map m) { - this.map = new HashMap(); - if (m != null) { + if (m == null) { + this.map = new HashMap(); + } else { + this.map = new HashMap(m.size()); for (final Entry e : m.entrySet()) { final Object value = e.getValue(); if (value != null) { @@ -308,7 +310,7 @@ public class JSONObject { * from the object. */ public JSONObject(Object object, String names[]) { - this(); + this(names.length); Class c = object.getClass(); for (int i = 0; i < names.length; i += 1) { String name = names[i]; @@ -377,6 +379,17 @@ public class JSONObject { } } } + + /** + * Constructor to specify an initial capacity of the internal map. Useful for library + * internal calls where we know, or at least can best guess, how big this JSONObject + * will be. + * + * @param initialCapacity initial capacity of the internal map. + */ + protected JSONObject(int initialCapacity){ + this.map = new HashMap(initialCapacity); + } /** * Accumulate values under a key. It is similar to the put method except diff --git a/Property.java b/Property.java index 4f1d7c4..51b97ed 100644 --- a/Property.java +++ b/Property.java @@ -41,7 +41,7 @@ public class Property { * @throws JSONException */ public static JSONObject toJSONObject(java.util.Properties properties) throws JSONException { - JSONObject jo = new JSONObject(); + JSONObject jo = new JSONObject(properties == null ? 0 : properties.size()); if (properties != null && !properties.isEmpty()) { Enumeration enumProperties = properties.propertyNames(); while(enumProperties.hasMoreElements()) {