4 Copyright (c) 2002 JSON.org
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
13 The above copyright notice and this permission notice shall be included in all
14 copies or substantial portions of the Software.
16 The Software shall be used for Good, not Evil.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 import java.io.IOException;
28 import java.io.StringWriter;
29 import java.io.Writer;
30 import java.lang.reflect.Array;
31 import java.math.BigDecimal;
32 import java.math.BigInteger;
33 import java.util.ArrayList;
34 import java.util.Collection;
35 import java.util.Iterator;
36 import java.util.List;
41 * A JSONArray is an ordered sequence of values. Its external text form is a
42 * string wrapped in square brackets with commas separating the values. The
43 * internal form is an object having <code>get</code> and <code>opt</code>
44 * methods for accessing the values by index, and <code>put</code> methods for
45 * adding or replacing values. The values can be any of these types:
46 * <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>,
47 * <code>Number</code>, <code>String</code>, or the
48 * <code>JSONObject.NULL object</code>.
50 * The constructor can convert a JSON text into a Java object. The
51 * <code>toString</code> method converts to JSON text.
53 * A <code>get</code> method returns a value if one can be found, and throws an
54 * exception if one cannot be found. An <code>opt</code> method returns a
55 * default value instead of throwing an exception, and so is useful for
56 * obtaining optional values.
58 * The generic <code>get()</code> and <code>opt()</code> methods return an
59 * object which you can cast or query for type. There are also typed
60 * <code>get</code> and <code>opt</code> methods that do type checking and type
63 * The texts produced by the <code>toString</code> methods strictly conform to
64 * JSON syntax rules. The constructors are more forgiving in the texts they will
67 * <li>An extra <code>,</code> <small>(comma)</small> may appear just
68 * before the closing bracket.</li>
69 * <li>The <code>null</code> value will be inserted when there is <code>,</code>
70 * <small>(comma)</small> elision.</li>
71 * <li>Strings may be quoted with <code>'</code> <small>(single
72 * quote)</small>.</li>
73 * <li>Strings do not need to be quoted at all if they do not begin with a quote
74 * or single quote, and if they do not contain leading or trailing spaces, and
75 * if they do not contain any of these characters:
76 * <code>{ } [ ] / \ : , #</code> and if they do not look like numbers and
77 * if they are not the reserved words <code>true</code>, <code>false</code>, or
78 * <code>null</code>.</li>
84 public class JSONArray implements Iterable<Object> {
87 * The arrayList where the JSONArray's properties are kept.
89 private final ArrayList<Object> myArrayList;
92 * Construct an empty JSONArray.
95 this.myArrayList = new ArrayList<Object>();
99 * Construct a JSONArray from a JSONTokener.
103 * @throws JSONException
104 * If there is a syntax error.
106 public JSONArray(JSONTokener x) throws JSONException {
108 if (x.nextClean() != '[') {
109 throw x.syntaxError("A JSONArray text must start with '['");
112 char nextChar = x.nextClean();
114 // array is unclosed. No ']' found, instead EOF
115 throw x.syntaxError("Expected a ',' or ']'");
117 if (nextChar != ']') {
120 if (x.nextClean() == ',') {
122 this.myArrayList.add(JSONObject.NULL);
125 this.myArrayList.add(x.nextValue());
127 switch (x.nextClean()) {
129 // array is unclosed. No ']' found, instead EOF
130 throw x.syntaxError("Expected a ',' or ']'");
132 nextChar = x.nextClean();
134 // array is unclosed. No ']' found, instead EOF
135 throw x.syntaxError("Expected a ',' or ']'");
137 if (nextChar == ']') {
145 throw x.syntaxError("Expected a ',' or ']'");
152 * Construct a JSONArray from a source JSON text.
155 * A string that begins with <code>[</code> <small>(left
156 * bracket)</small> and ends with <code>]</code>
157 * <small>(right bracket)</small>.
158 * @throws JSONException
159 * If there is a syntax error.
161 public JSONArray(String source) throws JSONException {
162 this(new JSONTokener(source));
166 * Construct a JSONArray from a Collection.
171 public JSONArray(Collection<?> collection) {
172 if (collection == null) {
173 this.myArrayList = new ArrayList<Object>();
175 this.myArrayList = new ArrayList<Object>(collection.size());
176 for (Object o: collection){
177 this.myArrayList.add(JSONObject.wrap(o));
183 * Construct a JSONArray from an array
185 * @throws JSONException
186 * If not an array or if an array value is non-finite number.
188 public JSONArray(Object array) throws JSONException {
190 if (array.getClass().isArray()) {
191 int length = Array.getLength(array);
192 this.myArrayList.ensureCapacity(length);
193 for (int i = 0; i < length; i += 1) {
194 this.put(JSONObject.wrap(Array.get(array, i)));
197 throw new JSONException(
198 "JSONArray initial value should be a string or collection or array.");
203 public Iterator<Object> iterator() {
204 return this.myArrayList.iterator();
208 * Get the object value associated with an index.
211 * The index must be between 0 and length() - 1.
212 * @return An object value.
213 * @throws JSONException
214 * If there is no value for the index.
216 public Object get(int index) throws JSONException {
217 Object object = this.opt(index);
218 if (object == null) {
219 throw new JSONException("JSONArray[" + index + "] not found.");
225 * Get the boolean value associated with an index. The string values "true"
226 * and "false" are converted to boolean.
229 * The index must be between 0 and length() - 1.
231 * @throws JSONException
232 * If there is no value for the index or if the value is not
233 * convertible to boolean.
235 public boolean getBoolean(int index) throws JSONException {
236 Object object = this.get(index);
237 if (object.equals(Boolean.FALSE)
238 || (object instanceof String && ((String) object)
239 .equalsIgnoreCase("false"))) {
241 } else if (object.equals(Boolean.TRUE)
242 || (object instanceof String && ((String) object)
243 .equalsIgnoreCase("true"))) {
246 throw new JSONException("JSONArray[" + index + "] is not a boolean.");
250 * Get the double value associated with an index.
253 * The index must be between 0 and length() - 1.
255 * @throws JSONException
256 * If the key is not found or if the value cannot be converted
259 public double getDouble(int index) throws JSONException {
260 Object object = this.get(index);
262 return object instanceof Number ? ((Number) object).doubleValue()
263 : Double.parseDouble((String) object);
264 } catch (Exception e) {
265 throw new JSONException("JSONArray[" + index + "] is not a number.", e);
270 * Get the float value associated with a key.
273 * The index must be between 0 and length() - 1.
274 * @return The numeric value.
275 * @throws JSONException
276 * if the key is not found or if the value is not a Number
277 * object and cannot be converted to a number.
279 public float getFloat(int index) throws JSONException {
280 Object object = this.get(index);
282 return object instanceof Number ? ((Number) object).floatValue()
283 : Float.parseFloat(object.toString());
284 } catch (Exception e) {
285 throw new JSONException("JSONArray[" + index
286 + "] is not a number.", e);
291 * Get the Number value associated with a key.
294 * The index must be between 0 and length() - 1.
295 * @return The numeric value.
296 * @throws JSONException
297 * if the key is not found or if the value is not a Number
298 * object and cannot be converted to a number.
300 public Number getNumber(int index) throws JSONException {
301 Object object = this.get(index);
303 if (object instanceof Number) {
304 return (Number)object;
306 return JSONObject.stringToNumber(object.toString());
307 } catch (Exception e) {
308 throw new JSONException("JSONArray[" + index + "] is not a number.", e);
313 * Get the enum value associated with an index.
316 * The type of enum to retrieve.
318 * The index must be between 0 and length() - 1.
319 * @return The enum value at the index location
320 * @throws JSONException
321 * if the key is not found or if the value cannot be converted
324 public <E extends Enum<E>> E getEnum(Class<E> clazz, int index) throws JSONException {
325 E val = optEnum(clazz, index);
327 // JSONException should really take a throwable argument.
328 // If it did, I would re-implement this with the Enum.valueOf
329 // method and place any thrown exception in the JSONException
330 throw new JSONException("JSONArray[" + index + "] is not an enum of type "
331 + JSONObject.quote(clazz.getSimpleName()) + ".");
337 * Get the BigDecimal value associated with an index.
340 * The index must be between 0 and length() - 1.
342 * @throws JSONException
343 * If the key is not found or if the value cannot be converted
346 public BigDecimal getBigDecimal (int index) throws JSONException {
347 Object object = this.get(index);
349 return new BigDecimal(object.toString());
350 } catch (Exception e) {
351 throw new JSONException("JSONArray[" + index +
352 "] could not convert to BigDecimal.", e);
357 * Get the BigInteger value associated with an index.
360 * The index must be between 0 and length() - 1.
362 * @throws JSONException
363 * If the key is not found or if the value cannot be converted
366 public BigInteger getBigInteger (int index) throws JSONException {
367 Object object = this.get(index);
369 return new BigInteger(object.toString());
370 } catch (Exception e) {
371 throw new JSONException("JSONArray[" + index +
372 "] could not convert to BigInteger.", e);
377 * Get the int value associated with an index.
380 * The index must be between 0 and length() - 1.
382 * @throws JSONException
383 * If the key is not found or if the value is not a number.
385 public int getInt(int index) throws JSONException {
386 Object object = this.get(index);
388 return object instanceof Number ? ((Number) object).intValue()
389 : Integer.parseInt((String) object);
390 } catch (Exception e) {
391 throw new JSONException("JSONArray[" + index + "] is not a number.", e);
396 * Get the JSONArray associated with an index.
399 * The index must be between 0 and length() - 1.
400 * @return A JSONArray value.
401 * @throws JSONException
402 * If there is no value for the index. or if the value is not a
405 public JSONArray getJSONArray(int index) throws JSONException {
406 Object object = this.get(index);
407 if (object instanceof JSONArray) {
408 return (JSONArray) object;
410 throw new JSONException("JSONArray[" + index + "] is not a JSONArray.");
414 * Get the JSONObject associated with an index.
418 * @return A JSONObject value.
419 * @throws JSONException
420 * If there is no value for the index or if the value is not a
423 public JSONObject getJSONObject(int index) throws JSONException {
424 Object object = this.get(index);
425 if (object instanceof JSONObject) {
426 return (JSONObject) object;
428 throw new JSONException("JSONArray[" + index + "] is not a JSONObject.");
432 * Get the long value associated with an index.
435 * The index must be between 0 and length() - 1.
437 * @throws JSONException
438 * If the key is not found or if the value cannot be converted
441 public long getLong(int index) throws JSONException {
442 Object object = this.get(index);
444 return object instanceof Number ? ((Number) object).longValue()
445 : Long.parseLong((String) object);
446 } catch (Exception e) {
447 throw new JSONException("JSONArray[" + index + "] is not a number.", e);
452 * Get the string associated with an index.
455 * The index must be between 0 and length() - 1.
456 * @return A string value.
457 * @throws JSONException
458 * If there is no string value for the index.
460 public String getString(int index) throws JSONException {
461 Object object = this.get(index);
462 if (object instanceof String) {
463 return (String) object;
465 throw new JSONException("JSONArray[" + index + "] not a string.");
469 * Determine if the value is <code>null</code>.
472 * The index must be between 0 and length() - 1.
473 * @return true if the value at the index is <code>null</code>, or if there is no value.
475 public boolean isNull(int index) {
476 return JSONObject.NULL.equals(this.opt(index));
480 * Make a string from the contents of this JSONArray. The
481 * <code>separator</code> string is inserted between each element. Warning:
482 * This method assumes that the data structure is acyclical.
485 * A string that will be inserted between the elements.
487 * @throws JSONException
488 * If the array contains an invalid number.
490 public String join(String separator) throws JSONException {
491 int len = this.length();
492 StringBuilder sb = new StringBuilder();
494 for (int i = 0; i < len; i += 1) {
496 sb.append(separator);
498 sb.append(JSONObject.valueToString(this.myArrayList.get(i)));
500 return sb.toString();
504 * Get the number of elements in the JSONArray, included nulls.
506 * @return The length (or size).
508 public int length() {
509 return this.myArrayList.size();
513 * Get the optional object value associated with an index.
516 * The index must be between 0 and length() - 1. If not, null is returned.
517 * @return An object value, or null if there is no object at that index.
519 public Object opt(int index) {
520 return (index < 0 || index >= this.length()) ? null : this.myArrayList
525 * Get the optional boolean value associated with an index. It returns false
526 * if there is no value at that index, or if the value is not Boolean.TRUE
527 * or the String "true".
530 * The index must be between 0 and length() - 1.
533 public boolean optBoolean(int index) {
534 return this.optBoolean(index, false);
538 * Get the optional boolean value associated with an index. It returns the
539 * defaultValue if there is no value at that index or if it is not a Boolean
540 * or the String "true" or "false" (case insensitive).
543 * The index must be between 0 and length() - 1.
544 * @param defaultValue
548 public boolean optBoolean(int index, boolean defaultValue) {
550 return this.getBoolean(index);
551 } catch (Exception e) {
557 * Get the optional double value associated with an index. NaN is returned
558 * if there is no value for the index, or if the value is not a number and
559 * cannot be converted to a number.
562 * The index must be between 0 and length() - 1.
565 public double optDouble(int index) {
566 return this.optDouble(index, Double.NaN);
570 * Get the optional double value associated with an index. The defaultValue
571 * is returned if there is no value for the index, or if the value is not a
572 * number and cannot be converted to a number.
576 * @param defaultValue
580 public double optDouble(int index, double defaultValue) {
581 Object val = this.opt(index);
582 if (JSONObject.NULL.equals(val)) {
585 if (val instanceof Number){
586 return ((Number) val).doubleValue();
588 if (val instanceof String) {
590 return Double.parseDouble((String) val);
591 } catch (Exception e) {
599 * Get the optional float value associated with an index. NaN is returned
600 * if there is no value for the index, or if the value is not a number and
601 * cannot be converted to a number.
604 * The index must be between 0 and length() - 1.
607 public float optFloat(int index) {
608 return this.optFloat(index, Float.NaN);
612 * Get the optional float value associated with an index. The defaultValue
613 * is returned if there is no value for the index, or if the value is not a
614 * number and cannot be converted to a number.
618 * @param defaultValue
622 public float optFloat(int index, float defaultValue) {
623 Object val = this.opt(index);
624 if (JSONObject.NULL.equals(val)) {
627 if (val instanceof Number){
628 return ((Number) val).floatValue();
630 if (val instanceof String) {
632 return Float.parseFloat((String) val);
633 } catch (Exception e) {
641 * Get the optional int value associated with an index. Zero is returned if
642 * there is no value for the index, or if the value is not a number and
643 * cannot be converted to a number.
646 * The index must be between 0 and length() - 1.
649 public int optInt(int index) {
650 return this.optInt(index, 0);
654 * Get the optional int value associated with an index. The defaultValue is
655 * returned if there is no value for the index, or if the value is not a
656 * number and cannot be converted to a number.
659 * The index must be between 0 and length() - 1.
660 * @param defaultValue
664 public int optInt(int index, int defaultValue) {
665 Object val = this.opt(index);
666 if (JSONObject.NULL.equals(val)) {
669 if (val instanceof Number){
670 return ((Number) val).intValue();
673 if (val instanceof String) {
675 return new BigDecimal(val.toString()).intValue();
676 } catch (Exception e) {
684 * Get the enum value associated with a key.
687 * The type of enum to retrieve.
689 * The index must be between 0 and length() - 1.
690 * @return The enum value at the index location or null if not found
692 public <E extends Enum<E>> E optEnum(Class<E> clazz, int index) {
693 return this.optEnum(clazz, index, null);
697 * Get the enum value associated with a key.
700 * The type of enum to retrieve.
702 * The index must be between 0 and length() - 1.
703 * @param defaultValue
704 * The default in case the value is not found
705 * @return The enum value at the index location or defaultValue if
706 * the value is not found or cannot be assigned to clazz
708 public <E extends Enum<E>> E optEnum(Class<E> clazz, int index, E defaultValue) {
710 Object val = this.opt(index);
711 if (JSONObject.NULL.equals(val)) {
714 if (clazz.isAssignableFrom(val.getClass())) {
715 // we just checked it!
716 @SuppressWarnings("unchecked")
720 return Enum.valueOf(clazz, val.toString());
721 } catch (IllegalArgumentException e) {
723 } catch (NullPointerException e) {
730 * Get the optional BigInteger value associated with an index. The
731 * defaultValue is returned if there is no value for the index, or if the
732 * value is not a number and cannot be converted to a number.
735 * The index must be between 0 and length() - 1.
736 * @param defaultValue
740 public BigInteger optBigInteger(int index, BigInteger defaultValue) {
741 Object val = this.opt(index);
742 if (JSONObject.NULL.equals(val)) {
745 if (val instanceof BigInteger){
746 return (BigInteger) val;
748 if (val instanceof BigDecimal){
749 return ((BigDecimal) val).toBigInteger();
751 if (val instanceof Double || val instanceof Float){
752 return new BigDecimal(((Number) val).doubleValue()).toBigInteger();
754 if (val instanceof Long || val instanceof Integer
755 || val instanceof Short || val instanceof Byte){
756 return BigInteger.valueOf(((Number) val).longValue());
759 final String valStr = val.toString();
760 if(JSONObject.isDecimalNotation(valStr)) {
761 return new BigDecimal(valStr).toBigInteger();
763 return new BigInteger(valStr);
764 } catch (Exception e) {
770 * Get the optional BigDecimal value associated with an index. The
771 * defaultValue is returned if there is no value for the index, or if the
772 * value is not a number and cannot be converted to a number.
775 * The index must be between 0 and length() - 1.
776 * @param defaultValue
780 public BigDecimal optBigDecimal(int index, BigDecimal defaultValue) {
781 Object val = this.opt(index);
782 if (JSONObject.NULL.equals(val)) {
785 if (val instanceof BigDecimal){
786 return (BigDecimal) val;
788 if (val instanceof BigInteger){
789 return new BigDecimal((BigInteger) val);
791 if (val instanceof Double || val instanceof Float){
792 return new BigDecimal(((Number) val).doubleValue());
794 if (val instanceof Long || val instanceof Integer
795 || val instanceof Short || val instanceof Byte){
796 return new BigDecimal(((Number) val).longValue());
799 return new BigDecimal(val.toString());
800 } catch (Exception e) {
806 * Get the optional JSONArray associated with an index.
810 * @return A JSONArray value, or null if the index has no value, or if the
811 * value is not a JSONArray.
813 public JSONArray optJSONArray(int index) {
814 Object o = this.opt(index);
815 return o instanceof JSONArray ? (JSONArray) o : null;
819 * Get the optional JSONObject associated with an index. Null is returned if
820 * the key is not found, or null if the index has no value, or if the value
821 * is not a JSONObject.
824 * The index must be between 0 and length() - 1.
825 * @return A JSONObject value.
827 public JSONObject optJSONObject(int index) {
828 Object o = this.opt(index);
829 return o instanceof JSONObject ? (JSONObject) o : null;
833 * Get the optional long value associated with an index. Zero is returned if
834 * there is no value for the index, or if the value is not a number and
835 * cannot be converted to a number.
838 * The index must be between 0 and length() - 1.
841 public long optLong(int index) {
842 return this.optLong(index, 0);
846 * Get the optional long value associated with an index. The defaultValue is
847 * returned if there is no value for the index, or if the value is not a
848 * number and cannot be converted to a number.
851 * The index must be between 0 and length() - 1.
852 * @param defaultValue
856 public long optLong(int index, long defaultValue) {
857 Object val = this.opt(index);
858 if (JSONObject.NULL.equals(val)) {
861 if (val instanceof Number){
862 return ((Number) val).longValue();
865 if (val instanceof String) {
867 return new BigDecimal(val.toString()).longValue();
868 } catch (Exception e) {
876 * Get an optional {@link Number} value associated with a key, or <code>null</code>
877 * if there is no such key or if the value is not a number. If the value is a string,
878 * an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method
879 * would be used in cases where type coercion of the number value is unwanted.
882 * The index must be between 0 and length() - 1.
883 * @return An object which is the value.
885 public Number optNumber(int index) {
886 return this.optNumber(index, null);
890 * Get an optional {@link Number} value associated with a key, or the default if there
891 * is no such key or if the value is not a number. If the value is a string,
892 * an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method
893 * would be used in cases where type coercion of the number value is unwanted.
896 * The index must be between 0 and length() - 1.
897 * @param defaultValue
899 * @return An object which is the value.
901 public Number optNumber(int index, Number defaultValue) {
902 Object val = this.opt(index);
903 if (JSONObject.NULL.equals(val)) {
906 if (val instanceof Number){
910 if (val instanceof String) {
912 return JSONObject.stringToNumber((String) val);
913 } catch (Exception e) {
921 * Get the optional string value associated with an index. It returns an
922 * empty string if there is no value at that index. If the value is not a
923 * string and is not null, then it is converted to a string.
926 * The index must be between 0 and length() - 1.
927 * @return A String value.
929 public String optString(int index) {
930 return this.optString(index, "");
934 * Get the optional string associated with an index. The defaultValue is
935 * returned if the key is not found.
938 * The index must be between 0 and length() - 1.
939 * @param defaultValue
941 * @return A String value.
943 public String optString(int index, String defaultValue) {
944 Object object = this.opt(index);
945 return JSONObject.NULL.equals(object) ? defaultValue : object
950 * Append a boolean value. This increases the array's length by one.
956 public JSONArray put(boolean value) {
957 return this.put(value ? Boolean.TRUE : Boolean.FALSE);
961 * Put a value in the JSONArray, where the value will be a JSONArray which
962 * is produced from a Collection.
965 * A Collection value.
967 * @throws JSONException
968 * If the value is non-finite number.
970 public JSONArray put(Collection<?> value) {
971 return this.put(new JSONArray(value));
975 * Append a double value. This increases the array's length by one.
980 * @throws JSONException
981 * if the value is not finite.
983 public JSONArray put(double value) throws JSONException {
984 return this.put(Double.valueOf(value));
988 * Append a float value. This increases the array's length by one.
993 * @throws JSONException
994 * if the value is not finite.
996 public JSONArray put(float value) throws JSONException {
997 return this.put(Float.valueOf(value));
1001 * Append an int value. This increases the array's length by one.
1007 public JSONArray put(int value) {
1008 return this.put(Integer.valueOf(value));
1012 * Append an long value. This increases the array's length by one.
1018 public JSONArray put(long value) {
1019 return this.put(Long.valueOf(value));
1023 * Put a value in the JSONArray, where the value will be a JSONObject which
1024 * is produced from a Map.
1029 * @throws JSONException
1030 * If a value in the map is non-finite number.
1031 * @throws NullPointerException
1032 * If a key in the map is <code>null</code>
1034 public JSONArray put(Map<?, ?> value) {
1035 return this.put(new JSONObject(value));
1039 * Append an object value. This increases the array's length by one.
1042 * An object value. The value should be a Boolean, Double,
1043 * Integer, JSONArray, JSONObject, Long, or String, or the
1044 * JSONObject.NULL object.
1046 * @throws JSONException
1047 * If the value is non-finite number.
1049 public JSONArray put(Object value) {
1050 JSONObject.testValidity(value);
1051 this.myArrayList.add(value);
1056 * Put or replace a boolean value in the JSONArray. If the index is greater
1057 * than the length of the JSONArray, then null elements will be added as
1058 * necessary to pad it out.
1065 * @throws JSONException
1066 * If the index is negative.
1068 public JSONArray put(int index, boolean value) throws JSONException {
1069 return this.put(index, value ? Boolean.TRUE : Boolean.FALSE);
1073 * Put a value in the JSONArray, where the value will be a JSONArray which
1074 * is produced from a Collection.
1079 * A Collection value.
1081 * @throws JSONException
1082 * If the index is negative or if the value is non-finite.
1084 public JSONArray put(int index, Collection<?> value) throws JSONException {
1085 return this.put(index, new JSONArray(value));
1089 * Put or replace a double value. If the index is greater than the length of
1090 * the JSONArray, then null elements will be added as necessary to pad it
1098 * @throws JSONException
1099 * If the index is negative or if the value is non-finite.
1101 public JSONArray put(int index, double value) throws JSONException {
1102 return this.put(index, Double.valueOf(value));
1106 * Put or replace a float value. If the index is greater than the length of
1107 * the JSONArray, then null elements will be added as necessary to pad it
1115 * @throws JSONException
1116 * If the index is negative or if the value is non-finite.
1118 public JSONArray put(int index, float value) throws JSONException {
1119 return this.put(index, Float.valueOf(value));
1123 * Put or replace an int value. If the index is greater than the length of
1124 * the JSONArray, then null elements will be added as necessary to pad it
1132 * @throws JSONException
1133 * If the index is negative.
1135 public JSONArray put(int index, int value) throws JSONException {
1136 return this.put(index, Integer.valueOf(value));
1140 * Put or replace a long value. If the index is greater than the length of
1141 * the JSONArray, then null elements will be added as necessary to pad it
1149 * @throws JSONException
1150 * If the index is negative.
1152 public JSONArray put(int index, long value) throws JSONException {
1153 return this.put(index, Long.valueOf(value));
1157 * Put a value in the JSONArray, where the value will be a JSONObject that
1158 * is produced from a Map.
1165 * @throws JSONException
1166 * If the index is negative or if the the value is an invalid
1168 * @throws NullPointerException
1169 * If a key in the map is <code>null</code>
1171 public JSONArray put(int index, Map<?, ?> value) throws JSONException {
1172 this.put(index, new JSONObject(value));
1177 * Put or replace an object value in the JSONArray. If the index is greater
1178 * than the length of the JSONArray, then null elements will be added as
1179 * necessary to pad it out.
1184 * The value to put into the array. The value should be a
1185 * Boolean, Double, Integer, JSONArray, JSONObject, Long, or
1186 * String, or the JSONObject.NULL object.
1188 * @throws JSONException
1189 * If the index is negative or if the the value is an invalid
1192 public JSONArray put(int index, Object value) throws JSONException {
1194 throw new JSONException("JSONArray[" + index + "] not found.");
1196 if (index < this.length()) {
1197 JSONObject.testValidity(value);
1198 this.myArrayList.set(index, value);
1201 if(index == this.length()){
1203 return this.put(value);
1205 // if we are inserting past the length, we want to grow the array all at once
1206 // instead of incrementally.
1207 this.myArrayList.ensureCapacity(index + 1);
1208 while (index != this.length()) {
1209 // we don't need to test validity of NULL objects
1210 this.myArrayList.add(JSONObject.NULL);
1212 return this.put(value);
1216 * Creates a JSONPointer using an initialization string and tries to
1217 * match it to an item within this JSONArray. For example, given a
1218 * JSONArray initialized with this document:
1224 * and this JSONPointer string:
1228 * Then this method will return the String "c"
1229 * A JSONPointerException may be thrown from code called by this method.
1231 * @param jsonPointer string that can be used to create a JSONPointer
1232 * @return the item matched by the JSONPointer, otherwise null
1234 public Object query(String jsonPointer) {
1235 return query(new JSONPointer(jsonPointer));
1239 * Uses a uaer initialized JSONPointer and tries to
1240 * match it to an item whithin this JSONArray. For example, given a
1241 * JSONArray initialized with this document:
1247 * and this JSONPointer:
1251 * Then this method will return the String "c"
1252 * A JSONPointerException may be thrown from code called by this method.
1254 * @param jsonPointer string that can be used to create a JSONPointer
1255 * @return the item matched by the JSONPointer, otherwise null
1257 public Object query(JSONPointer jsonPointer) {
1258 return jsonPointer.queryFrom(this);
1262 * Queries and returns a value from this object using {@code jsonPointer}, or
1263 * returns null if the query fails due to a missing key.
1265 * @param jsonPointer the string representation of the JSON pointer
1266 * @return the queried value or {@code null}
1267 * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
1269 public Object optQuery(String jsonPointer) {
1270 return optQuery(new JSONPointer(jsonPointer));
1274 * Queries and returns a value from this object using {@code jsonPointer}, or
1275 * returns null if the query fails due to a missing key.
1277 * @param jsonPointer The JSON pointer
1278 * @return the queried value or {@code null}
1279 * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
1281 public Object optQuery(JSONPointer jsonPointer) {
1283 return jsonPointer.queryFrom(this);
1284 } catch (JSONPointerException e) {
1290 * Remove an index and close the hole.
1293 * The index of the element to be removed.
1294 * @return The value that was associated with the index, or null if there
1297 public Object remove(int index) {
1298 return index >= 0 && index < this.length()
1299 ? this.myArrayList.remove(index)
1304 * Determine if two JSONArrays are similar.
1305 * They must contain similar sequences.
1307 * @param other The other JSONArray
1308 * @return true if they are equal
1310 public boolean similar(Object other) {
1311 if (!(other instanceof JSONArray)) {
1314 int len = this.length();
1315 if (len != ((JSONArray)other).length()) {
1318 for (int i = 0; i < len; i += 1) {
1319 Object valueThis = this.myArrayList.get(i);
1320 Object valueOther = ((JSONArray)other).myArrayList.get(i);
1321 if(valueThis == valueOther) {
1324 if(valueThis == null) {
1327 if (valueThis instanceof JSONObject) {
1328 if (!((JSONObject)valueThis).similar(valueOther)) {
1331 } else if (valueThis instanceof JSONArray) {
1332 if (!((JSONArray)valueThis).similar(valueOther)) {
1335 } else if (!valueThis.equals(valueOther)) {
1343 * Produce a JSONObject by combining a JSONArray of names with the values of
1347 * A JSONArray containing a list of key strings. These will be
1348 * paired with the values.
1349 * @return A JSONObject, or null if there are no names or if this JSONArray
1351 * @throws JSONException
1352 * If any of the names are null.
1354 public JSONObject toJSONObject(JSONArray names) throws JSONException {
1355 if (names == null || names.isEmpty() || this.isEmpty()) {
1358 JSONObject jo = new JSONObject(names.length());
1359 for (int i = 0; i < names.length(); i += 1) {
1360 jo.put(names.getString(i), this.opt(i));
1366 * Make a JSON text of this JSONArray. For compactness, no unnecessary
1367 * whitespace is added. If it is not possible to produce a syntactically
1368 * correct JSON text then null will be returned instead. This could occur if
1369 * the array contains an invalid number.
1371 * Warning: This method assumes that the data structure is acyclical.
1374 * @return a printable, displayable, transmittable representation of the
1378 public String toString() {
1380 return this.toString(0);
1381 } catch (Exception e) {
1387 * Make a pretty-printed JSON text of this JSONArray.
1389 * <p>If <code>indentFactor > 0</code> and the {@link JSONArray} has only
1390 * one element, then the array will be output on a single line:
1391 * <pre>{@code [1]}</pre>
1393 * <p>If an array has 2 or more elements, then it will be output across
1394 * multiple lines: <pre>{@code
1402 * Warning: This method assumes that the data structure is acyclical.
1405 * @param indentFactor
1406 * The number of spaces to add to each level of indentation.
1407 * @return a printable, displayable, transmittable representation of the
1408 * object, beginning with <code>[</code> <small>(left
1409 * bracket)</small> and ending with <code>]</code>
1410 * <small>(right bracket)</small>.
1411 * @throws JSONException
1413 public String toString(int indentFactor) throws JSONException {
1414 StringWriter sw = new StringWriter();
1415 synchronized (sw.getBuffer()) {
1416 return this.write(sw, indentFactor, 0).toString();
1421 * Write the contents of the JSONArray as JSON text to a writer. For
1422 * compactness, no whitespace is added.
1424 * Warning: This method assumes that the data structure is acyclical.
1427 * @return The writer.
1428 * @throws JSONException
1430 public Writer write(Writer writer) throws JSONException {
1431 return this.write(writer, 0, 0);
1435 * Write the contents of the JSONArray as JSON text to a writer.
1437 * <p>If <code>indentFactor > 0</code> and the {@link JSONArray} has only
1438 * one element, then the array will be output on a single line:
1439 * <pre>{@code [1]}</pre>
1441 * <p>If an array has 2 or more elements, then it will be output across
1442 * multiple lines: <pre>{@code
1450 * Warning: This method assumes that the data structure is acyclical.
1454 * Writes the serialized JSON
1455 * @param indentFactor
1456 * The number of spaces to add to each level of indentation.
1458 * The indentation of the top level.
1459 * @return The writer.
1460 * @throws JSONException
1462 public Writer write(Writer writer, int indentFactor, int indent)
1463 throws JSONException {
1465 boolean commanate = false;
1466 int length = this.length();
1471 JSONObject.writeValue(writer, this.myArrayList.get(0),
1472 indentFactor, indent);
1473 } catch (Exception e) {
1474 throw new JSONException("Unable to write JSONArray value at index: 0", e);
1476 } else if (length != 0) {
1477 final int newindent = indent + indentFactor;
1479 for (int i = 0; i < length; i += 1) {
1483 if (indentFactor > 0) {
1486 JSONObject.indent(writer, newindent);
1488 JSONObject.writeValue(writer, this.myArrayList.get(i),
1489 indentFactor, newindent);
1490 } catch (Exception e) {
1491 throw new JSONException("Unable to write JSONArray value at index: " + i, e);
1495 if (indentFactor > 0) {
1498 JSONObject.indent(writer, indent);
1502 } catch (IOException e) {
1503 throw new JSONException(e);
1508 * Returns a java.util.List containing all of the elements in this array.
1509 * If an element in the array is a JSONArray or JSONObject it will also
1512 * Warning: This method assumes that the data structure is acyclical.
1514 * @return a java.util.List containing the elements of this array
1516 public List<Object> toList() {
1517 List<Object> results = new ArrayList<Object>(this.myArrayList.size());
1518 for (Object element : this.myArrayList) {
1519 if (element == null || JSONObject.NULL.equals(element)) {
1521 } else if (element instanceof JSONArray) {
1522 results.add(((JSONArray) element).toList());
1523 } else if (element instanceof JSONObject) {
1524 results.add(((JSONObject) element).toMap());
1526 results.add(element);
1533 * Check if JSONArray is empty.
1535 * @return true if JSONArray is empty, otherwise false.
1537 public boolean isEmpty() {
1538 return myArrayList.isEmpty();