@@ -173,7 +173,37 @@ public JSONArray(Collection<?> collection) {
173173 this .myArrayList = new ArrayList <Object >();
174174 } else {
175175 this .myArrayList = new ArrayList <Object >(collection .size ());
176- this .addAll (collection );
176+ this .addAll (collection , true );
177+ }
178+ }
179+
180+ /**
181+ * Construct a JSONArray from an Iterable. This is a shallow copy.
182+ *
183+ * @param iter
184+ * A Iterable collection.
185+ */
186+ public JSONArray (Iterable <?> iter ) {
187+ this ();
188+ if (iter == null ) {
189+ return ;
190+ }
191+ this .addAll (iter , true );
192+ }
193+
194+ /**
195+ * Construct a JSONArray from another JSONArray. This is a shallow copy.
196+ *
197+ * @param array
198+ * A array.
199+ */
200+ public JSONArray (JSONArray array ) {
201+ if (array == null ) {
202+ this .myArrayList = new ArrayList <Object >();
203+ } else {
204+ // shallow copy directly the internal array lists as any wrapping
205+ // should have been done already in the original JSONArray
206+ this .myArrayList = new ArrayList <Object >(array .myArrayList );
177207 }
178208 }
179209
@@ -191,7 +221,11 @@ public JSONArray(Collection<?> collection) {
191221 */
192222 public JSONArray (Object array ) throws JSONException {
193223 this ();
194- this .addAll (array );
224+ if (!array .getClass ().isArray ()) {
225+ throw new JSONException (
226+ "JSONArray initial value should be a string or collection or array." );
227+ }
228+ this .addAll (array , true );
195229 }
196230
197231 /**
@@ -1165,32 +1199,58 @@ public JSONArray put(int index, Object value) throws JSONException {
11651199 }
11661200
11671201 /**
1168- * Put or replace a collection's elements in the JSONArray.
1202+ * Put a collection's elements in to the JSONArray.
11691203 *
11701204 * @param collection
11711205 * A Collection.
11721206 * @return this.
11731207 */
11741208 public JSONArray putAll (Collection <?> collection ) {
1175- this .addAll (collection );
1209+ this .addAll (collection , false );
1210+ return this ;
1211+ }
1212+
1213+ /**
1214+ * Put an Iterable's elements in to the JSONArray.
1215+ *
1216+ * @param iter
1217+ * An Iterable.
1218+ * @return this.
1219+ */
1220+ public JSONArray putAll (Iterable <?> iter ) {
1221+ this .addAll (iter , false );
11761222 return this ;
11771223 }
11781224
11791225 /**
1180- * Put or replace an array 's elements in the JSONArray.
1226+ * Put a JSONArray 's elements in to the JSONArray.
11811227 *
11821228 * @param array
1183- * Array. If the parameter passed is null, or not an array, an
1229+ * A JSONArray.
1230+ * @return this.
1231+ */
1232+ public JSONArray putAll (JSONArray array ) {
1233+ // directly copy the elements from the source array to this one
1234+ // as all wrapping should have been done already in the source.
1235+ this .myArrayList .addAll (array .myArrayList );
1236+ return this ;
1237+ }
1238+
1239+ /**
1240+ * Put an array's elements in to the JSONArray.
1241+ *
1242+ * @param array
1243+ * Array. If the parameter passed is null, or not an array or Iterable, an
11841244 * exception will be thrown.
11851245 * @return this.
11861246 *
11871247 * @throws JSONException
1188- * If not an array or if an array value is non-finite number.
1248+ * If not an array, JSONArray, Iterable or if an value is non-finite number.
11891249 * @throws NullPointerException
11901250 * Thrown if the array parameter is null.
11911251 */
11921252 public JSONArray putAll (Object array ) throws JSONException {
1193- this .addAll (array );
1253+ this .addAll (array , false );
11941254 return this ;
11951255 }
11961256
@@ -1520,39 +1580,88 @@ public boolean isEmpty() {
15201580 return this .myArrayList .isEmpty ();
15211581 }
15221582
1523-
15241583 /**
15251584 * Add a collection's elements to the JSONArray.
15261585 *
15271586 * @param collection
15281587 * A Collection.
1588+ * @param wrap
1589+ * {@code true} to call {@link JSONObject#wrap(Object)} for each item,
1590+ * {@code false} to add the items directly
1591+ *
15291592 */
1530- private void addAll (Collection <?> collection ) {
1593+ private void addAll (Collection <?> collection , boolean wrap ) {
15311594 this .myArrayList .ensureCapacity (this .myArrayList .size () + collection .size ());
1532- for (Object o : collection ){
1533- this .myArrayList .add (JSONObject .wrap (o ));
1595+ if (wrap ) {
1596+ for (Object o : collection ){
1597+ this .put (JSONObject .wrap (o ));
1598+ }
1599+ } else {
1600+ for (Object o : collection ){
1601+ this .put (o );
1602+ }
15341603 }
15351604 }
15361605
1606+ /**
1607+ * Add an Iterable's elements to the JSONArray.
1608+ *
1609+ * @param iter
1610+ * An Iterable.
1611+ * @param wrap
1612+ * {@code true} to call {@link JSONObject#wrap(Object)} for each item,
1613+ * {@code false} to add the items directly
1614+ */
1615+ private void addAll (Iterable <?> iter , boolean wrap ) {
1616+ if (wrap ) {
1617+ for (Object o : iter ){
1618+ this .put (JSONObject .wrap (o ));
1619+ }
1620+ } else {
1621+ for (Object o : iter ){
1622+ this .put (o );
1623+ }
1624+ }
1625+ }
1626+
15371627 /**
15381628 * Add an array's elements to the JSONArray.
15391629 *
15401630 * @param array
1541- * Array. If the parameter passed is null, or not an array, an
1542- * exception will be thrown.
1631+ * Array. If the parameter passed is null, or not an array,
1632+ * JSONArray, Collection, or Iterable, an exception will be
1633+ * thrown.
1634+ * @param wrap
1635+ * {@code true} to call {@link JSONObject#wrap(Object)} for each item,
1636+ * {@code false} to add the items directly
15431637 *
15441638 * @throws JSONException
15451639 * If not an array or if an array value is non-finite number.
15461640 * @throws NullPointerException
15471641 * Thrown if the array parameter is null.
15481642 */
1549- private void addAll (Object array ) throws JSONException {
1643+ private void addAll (Object array , boolean wrap ) throws JSONException {
15501644 if (array .getClass ().isArray ()) {
15511645 int length = Array .getLength (array );
15521646 this .myArrayList .ensureCapacity (this .myArrayList .size () + length );
1553- for (int i = 0 ; i < length ; i += 1 ) {
1554- this .put (JSONObject .wrap (Array .get (array , i )));
1647+ if (wrap ) {
1648+ for (int i = 0 ; i < length ; i += 1 ) {
1649+ this .put (JSONObject .wrap (Array .get (array , i )));
1650+ }
1651+ } else {
1652+ for (int i = 0 ; i < length ; i += 1 ) {
1653+ this .put (Array .get (array , i ));
1654+ }
15551655 }
1656+ } else if (array instanceof JSONArray ) {
1657+ // use the built in array list `addAll` as all object
1658+ // wrapping should have been completed in the original
1659+ // JSONArray
1660+ this .myArrayList .addAll (((JSONArray )array ).myArrayList );
1661+ } else if (array instanceof Collection ) {
1662+ this .addAll ((Collection <?>)array , wrap );
1663+ } else if (array instanceof Iterable ) {
1664+ this .addAll ((Iterable <?>)array , wrap );
15561665 } else {
15571666 throw new JSONException (
15581667 "JSONArray initial value should be a string or collection or array." );
0 commit comments