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;
40 * A JSONArray is an ordered sequence of values. Its external text form is a
41 * string wrapped in square brackets with commas separating the values. The
42 * internal form is an object having <code>get</code> and <code>opt</code>
43 * methods for accessing the values by index, and <code>put</code> methods for
44 * adding or replacing values. The values can be any of these types:
45 * <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>,
46 * <code>Number</code>, <code>String</code>, or the
47 * <code>JSONObject.NULL object</code>.
49 * The constructor can convert a JSON text into a Java object. The
50 * <code>toString</code> method converts to JSON text.
52 * A <code>get</code> method returns a value if one can be found, and throws an
53 * exception if one cannot be found. An <code>opt</code> method returns a
54 * default value instead of throwing an exception, and so is useful for
55 * obtaining optional values.
57 * The generic <code>get()</code> and <code>opt()</code> methods return an
58 * object which you can cast or query for type. There are also typed
59 * <code>get</code> and <code>opt</code> methods that do type checking and type
62 * The texts produced by the <code>toString</code> methods strictly conform to
63 * JSON syntax rules. The constructors are more forgiving in the texts they will
66 * <li>An extra <code>,</code> <small>(comma)</small> may appear just
67 * before the closing bracket.</li>
68 * <li>The <code>null</code> value will be inserted when there is <code>,</code>
69 * <small>(comma)</small> elision.</li>
70 * <li>Strings may be quoted with <code>'</code> <small>(single
71 * quote)</small>.</li>
72 * <li>Strings do not need to be quoted at all if they do not begin with a quote
73 * or single quote, and if they do not contain leading or trailing spaces, and
74 * if they do not contain any of these characters:
75 * <code>{ } [ ] / \ : , #</code> and if they do not look like numbers and if
76 * they are not the reserved words <code>true</code>, <code>false</code>, or
77 * <code>null</code>.</li>
83 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.
96 this.myArrayList = new ArrayList<Object>();
100 * Construct a JSONArray from a JSONTokener.
104 * @throws JSONException
105 * If there is a syntax error.
107 public JSONArray(JSONTokener x) throws JSONException
110 if (x.nextClean() != '[')
112 throw x.syntaxError("A JSONArray text must start with '['");
115 char nextChar = x.nextClean();
118 // array is unclosed. No ']' found, instead EOF
119 throw x.syntaxError("Expected a ',' or ']'");
126 if (x.nextClean() == ',')
129 this.myArrayList.add(JSONObject.NULL);
134 this.myArrayList.add(x.nextValue());
136 switch (x.nextClean())
139 // array is unclosed. No ']' found, instead EOF
140 throw x.syntaxError("Expected a ',' or ']'");
142 nextChar = x.nextClean();
145 // array is unclosed. No ']' found, instead EOF
146 throw x.syntaxError("Expected a ',' or ']'");
157 throw x.syntaxError("Expected a ',' or ']'");
164 * Construct a JSONArray from a source JSON text.
167 * A string that begins with <code>[</code> <small>(left
168 * bracket)</small> and ends with <code>]</code> <small>(right
170 * @throws JSONException
171 * If there is a syntax error.
173 public JSONArray(String source) throws JSONException
175 this(new JSONTokener(source));
179 * Construct a JSONArray from a Collection.
184 public JSONArray(Collection<?> collection)
186 if (collection == null)
188 this.myArrayList = new ArrayList<Object>();
192 this.myArrayList = new ArrayList<Object>(collection.size());
193 for (Object o : collection)
195 this.myArrayList.add(JSONObject.wrap(o));
201 * Construct a JSONArray from an array
203 * @throws JSONException
204 * If not an array or if an array value is non-finite number.
206 public JSONArray(Object array) throws JSONException
209 if (array.getClass().isArray())
211 int length = Array.getLength(array);
212 this.myArrayList.ensureCapacity(length);
213 for (int i = 0; i < length; i += 1)
215 this.put(JSONObject.wrap(Array.get(array, i)));
220 throw new JSONException(
221 "JSONArray initial value should be a string or collection or array.");
226 public Iterator<Object> iterator()
228 return this.myArrayList.iterator();
232 * Get the object value associated with an index.
235 * The index must be between 0 and length() - 1.
236 * @return An object value.
237 * @throws JSONException
238 * If there is no value for the index.
240 public Object get(int index) throws JSONException
242 Object object = this.opt(index);
245 throw new JSONException("JSONArray[" + index + "] not found.");
251 * Get the boolean value associated with an index. The string values "true"
252 * and "false" are converted to boolean.
255 * The index must be between 0 and length() - 1.
257 * @throws JSONException
258 * If there is no value for the index or if the value is not
259 * convertible to boolean.
261 public boolean getBoolean(int index) throws JSONException
263 Object object = this.get(index);
264 if (object.equals(Boolean.FALSE) || (object instanceof String
265 && ((String) object).equalsIgnoreCase("false")))
269 else if (object.equals(Boolean.TRUE) || (object instanceof String
270 && ((String) object).equalsIgnoreCase("true")))
274 throw new JSONException("JSONArray[" + index + "] is not a boolean.");
278 * Get the double value associated with an index.
281 * The index must be between 0 and length() - 1.
283 * @throws JSONException
284 * If the key is not found or if the value cannot be converted to a
287 public double getDouble(int index) throws JSONException
289 Object object = this.get(index);
292 return object instanceof Number ? ((Number) object).doubleValue()
293 : Double.parseDouble((String) object);
294 } catch (Exception e)
296 throw new JSONException("JSONArray[" + index + "] is not a number.",
302 * Get the float value associated with a key.
305 * The index must be between 0 and length() - 1.
306 * @return The numeric value.
307 * @throws JSONException
308 * if the key is not found or if the value is not a Number object
309 * and cannot be converted to a number.
311 public float getFloat(int index) throws JSONException
313 Object object = this.get(index);
316 return object instanceof Number ? ((Number) object).floatValue()
317 : Float.parseFloat(object.toString());
318 } catch (Exception e)
320 throw new JSONException("JSONArray[" + index + "] is not a number.",
326 * Get the Number value associated with a key.
329 * The index must be between 0 and length() - 1.
330 * @return The numeric value.
331 * @throws JSONException
332 * if the key is not found or if the value is not a Number object
333 * and cannot be converted to a number.
335 public Number getNumber(int index) throws JSONException
337 Object object = this.get(index);
340 if (object instanceof Number)
342 return (Number) object;
344 return JSONObject.stringToNumber(object.toString());
345 } catch (Exception e)
347 throw new JSONException("JSONArray[" + index + "] is not a number.",
353 * Get the enum value associated with an index.
356 * The type of enum to retrieve.
358 * The index must be between 0 and length() - 1.
359 * @return The enum value at the index location
360 * @throws JSONException
361 * if the key is not found or if the value cannot be converted to an
364 public <E extends Enum<E>> E getEnum(Class<E> clazz, int index)
367 E val = optEnum(clazz, index);
370 // JSONException should really take a throwable argument.
371 // If it did, I would re-implement this with the Enum.valueOf
372 // method and place any thrown exception in the JSONException
373 throw new JSONException(
374 "JSONArray[" + index + "] is not an enum of type "
375 + JSONObject.quote(clazz.getSimpleName()) + ".");
381 * Get the BigDecimal value associated with an index.
384 * The index must be between 0 and length() - 1.
386 * @throws JSONException
387 * If the key is not found or if the value cannot be converted to a
390 public BigDecimal getBigDecimal(int index) throws JSONException
392 Object object = this.get(index);
395 return new BigDecimal(object.toString());
396 } catch (Exception e)
398 throw new JSONException(
399 "JSONArray[" + index + "] could not convert to BigDecimal.",
405 * Get the BigInteger value associated with an index.
408 * The index must be between 0 and length() - 1.
410 * @throws JSONException
411 * If the key is not found or if the value cannot be converted to a
414 public BigInteger getBigInteger(int index) throws JSONException
416 Object object = this.get(index);
419 return new BigInteger(object.toString());
420 } catch (Exception e)
422 throw new JSONException(
423 "JSONArray[" + index + "] could not convert to BigInteger.",
429 * Get the int value associated with an index.
432 * The index must be between 0 and length() - 1.
434 * @throws JSONException
435 * If the key is not found or if the value is not a number.
437 public int getInt(int index) throws JSONException
439 Object object = this.get(index);
442 return object instanceof Number ? ((Number) object).intValue()
443 : Integer.parseInt((String) object);
444 } catch (Exception e)
446 throw new JSONException("JSONArray[" + index + "] is not a number.",
452 * Get the JSONArray associated with an index.
455 * The index must be between 0 and length() - 1.
456 * @return A JSONArray value.
457 * @throws JSONException
458 * If there is no value for the index. or if the value is not a
461 public JSONArray getJSONArray(int index) throws JSONException
463 Object object = this.get(index);
464 if (object instanceof JSONArray)
466 return (JSONArray) object;
468 throw new JSONException("JSONArray[" + index + "] is not a JSONArray.");
472 * Get the JSONObject associated with an index.
476 * @return A JSONObject value.
477 * @throws JSONException
478 * If there is no value for the index or if the value is not a
481 public JSONObject getJSONObject(int index) throws JSONException
483 Object object = this.get(index);
484 if (object instanceof JSONObject)
486 return (JSONObject) object;
488 throw new JSONException(
489 "JSONArray[" + index + "] is not a JSONObject.");
493 * Get the long value associated with an index.
496 * The index must be between 0 and length() - 1.
498 * @throws JSONException
499 * If the key is not found or if the value cannot be converted to a
502 public long getLong(int index) throws JSONException
504 Object object = this.get(index);
507 return object instanceof Number ? ((Number) object).longValue()
508 : Long.parseLong((String) object);
509 } catch (Exception e)
511 throw new JSONException("JSONArray[" + index + "] is not a number.",
517 * Get the string associated with an index.
520 * The index must be between 0 and length() - 1.
521 * @return A string value.
522 * @throws JSONException
523 * If there is no string value for the index.
525 public String getString(int index) throws JSONException
527 Object object = this.get(index);
528 if (object instanceof String)
530 return (String) object;
532 throw new JSONException("JSONArray[" + index + "] not a string.");
536 * Determine if the value is <code>null</code>.
539 * The index must be between 0 and length() - 1.
540 * @return true if the value at the index is <code>null</code>, or if there is
543 public boolean isNull(int index)
545 return JSONObject.NULL.equals(this.opt(index));
549 * Make a string from the contents of this JSONArray. The
550 * <code>separator</code> string is inserted between each element. Warning:
551 * This method assumes that the data structure is acyclical.
554 * A string that will be inserted between the elements.
556 * @throws JSONException
557 * If the array contains an invalid number.
559 public String join(String separator) throws JSONException
561 int len = this.length();
562 StringBuilder sb = new StringBuilder();
564 for (int i = 0; i < len; i += 1)
568 sb.append(separator);
570 sb.append(JSONObject.valueToString(this.myArrayList.get(i)));
572 return sb.toString();
576 * Get the number of elements in the JSONArray, included nulls.
578 * @return The length (or size).
582 return this.myArrayList.size();
586 * Get the optional object value associated with an index.
589 * The index must be between 0 and length() - 1. If not, null is
591 * @return An object value, or null if there is no object at that index.
593 public Object opt(int index)
595 return (index < 0 || index >= this.length()) ? null
596 : this.myArrayList.get(index);
600 * Get the optional boolean value associated with an index. It returns false
601 * if there is no value at that index, or if the value is not Boolean.TRUE or
605 * The index must be between 0 and length() - 1.
608 public boolean optBoolean(int index)
610 return this.optBoolean(index, false);
614 * Get the optional boolean value associated with an index. It returns the
615 * defaultValue if there is no value at that index or if it is not a Boolean
616 * or the String "true" or "false" (case insensitive).
619 * The index must be between 0 and length() - 1.
620 * @param defaultValue
624 public boolean optBoolean(int index, boolean defaultValue)
628 return this.getBoolean(index);
629 } catch (Exception e)
636 * Get the optional double value associated with an index. NaN is returned if
637 * there is no value for the index, or if the value is not a number and cannot
638 * be converted to a number.
641 * The index must be between 0 and length() - 1.
644 public double optDouble(int index)
646 return this.optDouble(index, Double.NaN);
650 * Get the optional double value associated with an index. The defaultValue is
651 * returned if there is no value for the index, or if the value is not a
652 * number and cannot be converted to a number.
656 * @param defaultValue
660 public double optDouble(int index, double defaultValue)
662 Object val = this.opt(index);
663 if (JSONObject.NULL.equals(val))
667 if (val instanceof Number)
669 return ((Number) val).doubleValue();
671 if (val instanceof String)
675 return Double.parseDouble((String) val);
676 } catch (Exception e)
685 * Get the optional float value associated with an index. NaN is returned if
686 * there is no value for the index, or if the value is not a number and cannot
687 * be converted to a number.
690 * The index must be between 0 and length() - 1.
693 public float optFloat(int index)
695 return this.optFloat(index, Float.NaN);
699 * Get the optional float value associated with an index. The defaultValue is
700 * returned if there is no value for the index, or if the value is not a
701 * number and cannot be converted to a number.
705 * @param defaultValue
709 public float optFloat(int index, float defaultValue)
711 Object val = this.opt(index);
712 if (JSONObject.NULL.equals(val))
716 if (val instanceof Number)
718 return ((Number) val).floatValue();
720 if (val instanceof String)
724 return Float.parseFloat((String) val);
725 } catch (Exception e)
734 * Get the optional int value associated with an index. Zero is returned if
735 * there is no value for the index, or if the value is not a number and cannot
736 * be converted to a number.
739 * The index must be between 0 and length() - 1.
742 public int optInt(int index)
744 return this.optInt(index, 0);
748 * Get the optional int value associated with an index. The defaultValue is
749 * returned if there is no value for the index, or if the value is not a
750 * number and cannot be converted to a number.
753 * The index must be between 0 and length() - 1.
754 * @param defaultValue
758 public int optInt(int index, int defaultValue)
760 Object val = this.opt(index);
761 if (JSONObject.NULL.equals(val))
765 if (val instanceof Number)
767 return ((Number) val).intValue();
770 if (val instanceof String)
774 return new BigDecimal(val.toString()).intValue();
775 } catch (Exception e)
784 * Get the enum value associated with a key.
787 * The type of enum to retrieve.
789 * The index must be between 0 and length() - 1.
790 * @return The enum value at the index location or null if not found
792 public <E extends Enum<E>> E optEnum(Class<E> clazz, int index)
794 return this.optEnum(clazz, index, null);
798 * Get the enum value associated with a key.
801 * The type of enum to retrieve.
803 * The index must be between 0 and length() - 1.
804 * @param defaultValue
805 * The default in case the value is not found
806 * @return The enum value at the index location or defaultValue if the value
807 * is not found or cannot be assigned to clazz
809 public <E extends Enum<E>> E optEnum(Class<E> clazz, int index,
814 Object val = this.opt(index);
815 if (JSONObject.NULL.equals(val))
819 if (clazz.isAssignableFrom(val.getClass()))
821 // we just checked it!
822 @SuppressWarnings("unchecked")
826 return Enum.valueOf(clazz, val.toString());
827 } catch (IllegalArgumentException e)
830 } catch (NullPointerException e)
837 * Get the optional BigInteger value associated with an index. The
838 * defaultValue is returned if there is no value for the index, or if the
839 * value is not a number and cannot be converted to a number.
842 * The index must be between 0 and length() - 1.
843 * @param defaultValue
847 public BigInteger optBigInteger(int index, BigInteger defaultValue)
849 Object val = this.opt(index);
850 if (JSONObject.NULL.equals(val))
854 if (val instanceof BigInteger)
856 return (BigInteger) val;
858 if (val instanceof BigDecimal)
860 return ((BigDecimal) val).toBigInteger();
862 if (val instanceof Double || val instanceof Float)
864 return new BigDecimal(((Number) val).doubleValue()).toBigInteger();
866 if (val instanceof Long || val instanceof Integer
867 || val instanceof Short || val instanceof Byte)
869 return BigInteger.valueOf(((Number) val).longValue());
873 final String valStr = val.toString();
874 if (JSONObject.isDecimalNotation(valStr))
876 return new BigDecimal(valStr).toBigInteger();
878 return new BigInteger(valStr);
879 } catch (Exception e)
886 * Get the optional BigDecimal value associated with an index. The
887 * defaultValue is returned if there is no value for the index, or if the
888 * value is not a number and cannot be converted to a number.
891 * The index must be between 0 and length() - 1.
892 * @param defaultValue
896 public BigDecimal optBigDecimal(int index, BigDecimal defaultValue)
898 Object val = this.opt(index);
899 if (JSONObject.NULL.equals(val))
903 if (val instanceof BigDecimal)
905 return (BigDecimal) val;
907 if (val instanceof BigInteger)
909 return new BigDecimal((BigInteger) val);
911 if (val instanceof Double || val instanceof Float)
913 return new BigDecimal(((Number) val).doubleValue());
915 if (val instanceof Long || val instanceof Integer
916 || val instanceof Short || val instanceof Byte)
918 return new BigDecimal(((Number) val).longValue());
922 return new BigDecimal(val.toString());
923 } catch (Exception e)
930 * Get the optional JSONArray associated with an index.
934 * @return A JSONArray value, or null if the index has no value, or if the
935 * value is not a JSONArray.
937 public JSONArray optJSONArray(int index)
939 Object o = this.opt(index);
940 return o instanceof JSONArray ? (JSONArray) o : null;
944 * Get the optional JSONObject associated with an index. Null is returned if
945 * the key is not found, or null if the index has no value, or if the value is
949 * The index must be between 0 and length() - 1.
950 * @return A JSONObject value.
952 public JSONObject optJSONObject(int index)
954 Object o = this.opt(index);
955 return o instanceof JSONObject ? (JSONObject) o : null;
959 * Get the optional long value associated with an index. Zero is returned if
960 * there is no value for the index, or if the value is not a number and cannot
961 * be converted to a number.
964 * The index must be between 0 and length() - 1.
967 public long optLong(int index)
969 return this.optLong(index, 0);
973 * Get the optional long value associated with an index. The defaultValue is
974 * returned if there is no value for the index, or if the value is not a
975 * number and cannot be converted to a number.
978 * The index must be between 0 and length() - 1.
979 * @param defaultValue
983 public long optLong(int index, long defaultValue)
985 Object val = this.opt(index);
986 if (JSONObject.NULL.equals(val))
990 if (val instanceof Number)
992 return ((Number) val).longValue();
995 if (val instanceof String)
999 return new BigDecimal(val.toString()).longValue();
1000 } catch (Exception e)
1002 return defaultValue;
1005 return defaultValue;
1009 * Get an optional {@link Number} value associated with a key, or
1010 * <code>null</code> if there is no such key or if the value is not a number.
1011 * If the value is a string, an attempt will be made to evaluate it as a
1012 * number ({@link BigDecimal}). This method would be used in cases where type
1013 * coercion of the number value is unwanted.
1016 * The index must be between 0 and length() - 1.
1017 * @return An object which is the value.
1019 public Number optNumber(int index)
1021 return this.optNumber(index, null);
1025 * Get an optional {@link Number} value associated with a key, or the default
1026 * if there is no such key or if the value is not a number. If the value is a
1027 * string, an attempt will be made to evaluate it as a number
1028 * ({@link BigDecimal}). This method would be used in cases where type
1029 * coercion of the number value is unwanted.
1032 * The index must be between 0 and length() - 1.
1033 * @param defaultValue
1035 * @return An object which is the value.
1037 public Number optNumber(int index, Number defaultValue)
1039 Object val = this.opt(index);
1040 if (JSONObject.NULL.equals(val))
1042 return defaultValue;
1044 if (val instanceof Number)
1046 return (Number) val;
1049 if (val instanceof String)
1053 return JSONObject.stringToNumber((String) val);
1054 } catch (Exception e)
1056 return defaultValue;
1059 return defaultValue;
1063 * Get the optional string value associated with an index. It returns an empty
1064 * string if there is no value at that index. If the value is not a string and
1065 * is not null, then it is converted to a string.
1068 * The index must be between 0 and length() - 1.
1069 * @return A String value.
1071 public String optString(int index)
1073 return this.optString(index, "");
1077 * Get the optional string associated with an index. The defaultValue is
1078 * returned if the key is not found.
1081 * The index must be between 0 and length() - 1.
1082 * @param defaultValue
1083 * The default value.
1084 * @return A String value.
1086 public String optString(int index, String defaultValue)
1088 Object object = this.opt(index);
1089 return JSONObject.NULL.equals(object) ? defaultValue
1090 : object.toString();
1094 * Append a boolean value. This increases the array's length by one.
1100 public JSONArray put(boolean value)
1102 return this.put(value ? Boolean.TRUE : Boolean.FALSE);
1106 * Put a value in the JSONArray, where the value will be a JSONArray which is
1107 * produced from a Collection.
1110 * A Collection value.
1112 * @throws JSONException
1113 * If the value is non-finite number.
1115 public JSONArray put(Collection<?> value)
1117 return this.put(new JSONArray(value));
1121 * Append a double value. This increases the array's length by one.
1126 * @throws JSONException
1127 * if the value is not finite.
1129 public JSONArray put(double value) throws JSONException
1131 return this.put(Double.valueOf(value));
1135 * Append a float value. This increases the array's length by one.
1140 * @throws JSONException
1141 * if the value is not finite.
1143 public JSONArray put(float value) throws JSONException
1145 return this.put(Float.valueOf(value));
1149 * Append an int value. This increases the array's length by one.
1155 public JSONArray put(int value)
1157 return this.put(Integer.valueOf(value));
1161 * Append an long value. This increases the array's length by one.
1167 public JSONArray put(long value)
1169 return this.put(Long.valueOf(value));
1173 * Put a value in the JSONArray, where the value will be a JSONObject which is
1174 * produced from a Map.
1179 * @throws JSONException
1180 * If a value in the map is non-finite number.
1181 * @throws NullPointerException
1182 * If a key in the map is <code>null</code>
1184 public JSONArray put(Map<?, ?> value)
1186 return this.put(new JSONObject(value));
1190 * Append an object value. This increases the array's length by one.
1193 * An object value. The value should be a Boolean, Double, Integer,
1194 * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL
1197 * @throws JSONException
1198 * If the value is non-finite number.
1200 public JSONArray put(Object value)
1202 JSONObject.testValidity(value);
1203 this.myArrayList.add(value);
1208 * Put or replace a boolean value in the JSONArray. If the index is greater
1209 * than the length of the JSONArray, then null elements will be added as
1210 * necessary to pad it out.
1217 * @throws JSONException
1218 * If the index is negative.
1220 public JSONArray put(int index, boolean value) throws JSONException
1222 return this.put(index, value ? Boolean.TRUE : Boolean.FALSE);
1226 * Put a value in the JSONArray, where the value will be a JSONArray which is
1227 * produced from a Collection.
1232 * A Collection value.
1234 * @throws JSONException
1235 * If the index is negative or if the value is non-finite.
1237 public JSONArray put(int index, Collection<?> value) throws JSONException
1239 return this.put(index, new JSONArray(value));
1243 * Put or replace a double value. If the index is greater than the length of
1244 * the JSONArray, then null elements will be added as necessary to pad it out.
1251 * @throws JSONException
1252 * If the index is negative or if the value is non-finite.
1254 public JSONArray put(int index, double value) throws JSONException
1256 return this.put(index, Double.valueOf(value));
1260 * Put or replace a float value. If the index is greater than the length of
1261 * the JSONArray, then null elements will be added as necessary to pad it out.
1268 * @throws JSONException
1269 * If the index is negative or if the value is non-finite.
1271 public JSONArray put(int index, float value) throws JSONException
1273 return this.put(index, Float.valueOf(value));
1277 * Put or replace an int value. If the index is greater than the length of the
1278 * JSONArray, then null elements will be added as necessary to pad it out.
1285 * @throws JSONException
1286 * If the index is negative.
1288 public JSONArray put(int index, int value) throws JSONException
1290 return this.put(index, Integer.valueOf(value));
1294 * Put or replace a long value. If the index is greater than the length of the
1295 * JSONArray, then null elements will be added as necessary to pad it out.
1302 * @throws JSONException
1303 * If the index is negative.
1305 public JSONArray put(int index, long value) throws JSONException
1307 return this.put(index, Long.valueOf(value));
1311 * Put a value in the JSONArray, where the value will be a JSONObject that is
1312 * produced from a Map.
1319 * @throws JSONException
1320 * If the index is negative or if the the value is an invalid
1322 * @throws NullPointerException
1323 * If a key in the map is <code>null</code>
1325 public JSONArray put(int index, Map<?, ?> value) throws JSONException
1327 this.put(index, new JSONObject(value));
1332 * Put or replace an object value in the JSONArray. If the index is greater
1333 * than the length of the JSONArray, then null elements will be added as
1334 * necessary to pad it out.
1339 * The value to put into the array. The value should be a Boolean,
1340 * Double, Integer, JSONArray, JSONObject, Long, or String, or the
1341 * JSONObject.NULL object.
1343 * @throws JSONException
1344 * If the index is negative or if the the value is an invalid
1347 public JSONArray put(int index, Object value) throws JSONException
1351 throw new JSONException("JSONArray[" + index + "] not found.");
1353 if (index < this.length())
1355 JSONObject.testValidity(value);
1356 this.myArrayList.set(index, value);
1359 if (index == this.length())
1362 return this.put(value);
1364 // if we are inserting past the length, we want to grow the array all at
1366 // instead of incrementally.
1367 this.myArrayList.ensureCapacity(index + 1);
1368 while (index != this.length())
1370 // we don't need to test validity of NULL objects
1371 this.myArrayList.add(JSONObject.NULL);
1373 return this.put(value);
1377 * Creates a JSONPointer using an initialization string and tries to match it
1378 * to an item within this JSONArray. For example, given a JSONArray
1379 * initialized with this document:
1387 * and this JSONPointer string:
1393 * Then this method will return the String "c" A JSONPointerException may be
1394 * thrown from code called by this method.
1396 * @param jsonPointer
1397 * string that can be used to create a JSONPointer
1398 * @return the item matched by the JSONPointer, otherwise null
1400 public Object query(String jsonPointer)
1402 return query(new JSONPointer(jsonPointer));
1406 * Uses a uaer initialized JSONPointer and tries to match it to an item
1407 * whithin this JSONArray. For example, given a JSONArray initialized with
1416 * and this JSONPointer:
1422 * Then this method will return the String "c" A JSONPointerException may be
1423 * thrown from code called by this method.
1425 * @param jsonPointer
1426 * string that can be used to create a JSONPointer
1427 * @return the item matched by the JSONPointer, otherwise null
1429 public Object query(JSONPointer jsonPointer)
1431 return jsonPointer.queryFrom(this);
1435 * Queries and returns a value from this object using {@code jsonPointer}, or
1436 * returns null if the query fails due to a missing key.
1438 * @param jsonPointer
1439 * the string representation of the JSON pointer
1440 * @return the queried value or {@code null}
1441 * @throws IllegalArgumentException
1442 * if {@code jsonPointer} has invalid syntax
1444 public Object optQuery(String jsonPointer)
1446 return optQuery(new JSONPointer(jsonPointer));
1450 * Queries and returns a value from this object using {@code jsonPointer}, or
1451 * returns null if the query fails due to a missing key.
1453 * @param jsonPointer
1455 * @return the queried value or {@code null}
1456 * @throws IllegalArgumentException
1457 * if {@code jsonPointer} has invalid syntax
1459 public Object optQuery(JSONPointer jsonPointer)
1463 return jsonPointer.queryFrom(this);
1464 } catch (JSONPointerException e)
1471 * Remove an index and close the hole.
1474 * The index of the element to be removed.
1475 * @return The value that was associated with the index, or null if there was
1478 public Object remove(int index)
1480 return index >= 0 && index < this.length()
1481 ? this.myArrayList.remove(index)
1486 * Determine if two JSONArrays are similar. They must contain similar
1490 * The other JSONArray
1491 * @return true if they are equal
1493 public boolean similar(Object other)
1495 if (!(other instanceof JSONArray))
1499 int len = this.length();
1500 if (len != ((JSONArray) other).length())
1504 for (int i = 0; i < len; i += 1)
1506 Object valueThis = this.myArrayList.get(i);
1507 Object valueOther = ((JSONArray) other).myArrayList.get(i);
1508 if (valueThis == valueOther)
1512 if (valueThis == null)
1516 if (valueThis instanceof JSONObject)
1518 if (!((JSONObject) valueThis).similar(valueOther))
1523 else if (valueThis instanceof JSONArray)
1525 if (!((JSONArray) valueThis).similar(valueOther))
1530 else if (!valueThis.equals(valueOther))
1539 * Produce a JSONObject by combining a JSONArray of names with the values of
1543 * A JSONArray containing a list of key strings. These will be paired
1545 * @return A JSONObject, or null if there are no names or if this JSONArray
1547 * @throws JSONException
1548 * If any of the names are null.
1550 public JSONObject toJSONObject(JSONArray names) throws JSONException
1552 if (names == null || names.isEmpty() || this.isEmpty())
1556 JSONObject jo = new JSONObject(names.length());
1557 for (int i = 0; i < names.length(); i += 1)
1559 jo.put(names.getString(i), this.opt(i));
1565 * Make a JSON text of this JSONArray. For compactness, no unnecessary
1566 * whitespace is added. If it is not possible to produce a syntactically
1567 * correct JSON text then null will be returned instead. This could occur if
1568 * the array contains an invalid number.
1570 * <b> Warning: This method assumes that the data structure is acyclical. </b>
1572 * @return a printable, displayable, transmittable representation of the
1576 public String toString()
1580 return this.toString(0);
1581 } catch (Exception e)
1588 * Make a pretty-printed JSON text of this JSONArray.
1591 * If <code>indentFactor > 0</code> and the {@link JSONArray} has only one
1592 * element, then the array will be output on a single line:
1599 * If an array has 2 or more elements, then it will be output across multiple
1612 * <b> Warning: This method assumes that the data structure is acyclical. </b>
1614 * @param indentFactor
1615 * The number of spaces to add to each level of indentation.
1616 * @return a printable, displayable, transmittable representation of the
1617 * object, beginning with <code>[</code> <small>(left
1618 * bracket)</small> and ending with <code>]</code> <small>(right
1620 * @throws JSONException
1622 public String toString(int indentFactor) throws JSONException
1624 StringWriter sw = new StringWriter();
1625 synchronized (sw.getBuffer())
1627 return this.write(sw, indentFactor, 0).toString();
1632 * Write the contents of the JSONArray as JSON text to a writer. For
1633 * compactness, no whitespace is added.
1635 * <b> Warning: This method assumes that the data structure is acyclical. </b>
1637 * @return The writer.
1638 * @throws JSONException
1640 public Writer write(Writer writer) throws JSONException
1642 return this.write(writer, 0, 0);
1646 * Write the contents of the JSONArray as JSON text to a writer.
1649 * If <code>indentFactor > 0</code> and the {@link JSONArray} has only one
1650 * element, then the array will be output on a single line:
1657 * If an array has 2 or more elements, then it will be output across multiple
1670 * <b> Warning: This method assumes that the data structure is acyclical. </b>
1673 * Writes the serialized JSON
1674 * @param indentFactor
1675 * The number of spaces to add to each level of indentation.
1677 * The indentation of the top level.
1678 * @return The writer.
1679 * @throws JSONException
1681 public Writer write(Writer writer, int indentFactor, int indent)
1682 throws JSONException
1686 boolean commanate = false;
1687 int length = this.length();
1694 JSONObject.writeValue(writer, this.myArrayList.get(0),
1695 indentFactor, indent);
1696 } catch (Exception e)
1698 throw new JSONException(
1699 "Unable to write JSONArray value at index: 0", e);
1702 else if (length != 0)
1704 final int newindent = indent + indentFactor;
1706 for (int i = 0; i < length; i += 1)
1712 if (indentFactor > 0)
1716 JSONObject.indent(writer, newindent);
1719 JSONObject.writeValue(writer, this.myArrayList.get(i),
1720 indentFactor, newindent);
1721 } catch (Exception e)
1723 throw new JSONException(
1724 "Unable to write JSONArray value at index: " + i, e);
1728 if (indentFactor > 0)
1732 JSONObject.indent(writer, indent);
1736 } catch (IOException e)
1738 throw new JSONException(e);
1743 * Returns a java.util.List containing all of the elements in this array. If
1744 * an element in the array is a JSONArray or JSONObject it will also be
1747 * Warning: This method assumes that the data structure is acyclical.
1749 * @return a java.util.List containing the elements of this array
1751 public List<Object> toList()
1753 List<Object> results = new ArrayList<Object>(this.myArrayList.size());
1754 for (Object element : this.myArrayList)
1756 if (element == null || JSONObject.NULL.equals(element))
1760 else if (element instanceof JSONArray)
1762 results.add(((JSONArray) element).toList());
1764 else if (element instanceof JSONObject)
1766 results.add(((JSONObject) element).toMap());
1770 results.add(element);
1777 * Check if JSONArray is empty.
1779 * @return true if JSONArray is empty, otherwise false.
1781 public boolean isEmpty()
1783 return myArrayList.isEmpty();