2021-01-20 17:10:45 +08:00
|
|
|
|
package cn.hutool.json;
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.bean.BeanPath;
|
|
|
|
|
import cn.hutool.core.collection.ArrayIter;
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
2021-10-15 01:27:16 +08:00
|
|
|
|
import cn.hutool.core.lang.Filter;
|
2021-10-30 02:23:28 +08:00
|
|
|
|
import cn.hutool.core.lang.mutable.MutablePair;
|
2021-06-26 23:49:43 +08:00
|
|
|
|
import cn.hutool.core.text.StrJoiner;
|
2021-01-20 17:10:45 +08:00
|
|
|
|
import cn.hutool.core.util.ArrayUtil;
|
2021-09-08 11:55:09 +08:00
|
|
|
|
import cn.hutool.core.util.ObjectUtil;
|
2021-01-20 17:10:45 +08:00
|
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
|
|
import cn.hutool.core.util.TypeUtil;
|
|
|
|
|
import cn.hutool.json.serialize.GlobalSerializeMapping;
|
|
|
|
|
import cn.hutool.json.serialize.JSONSerializer;
|
2021-06-26 16:56:47 +08:00
|
|
|
|
import cn.hutool.json.serialize.JSONWriter;
|
2021-01-20 17:10:45 +08:00
|
|
|
|
|
2021-10-15 01:27:16 +08:00
|
|
|
|
import java.io.StringWriter;
|
2021-01-20 17:10:45 +08:00
|
|
|
|
import java.io.Writer;
|
2022-03-31 18:01:55 +08:00
|
|
|
|
import java.lang.reflect.Type;
|
2021-01-20 17:10:45 +08:00
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Collection;
|
|
|
|
|
import java.util.Iterator;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.ListIterator;
|
|
|
|
|
import java.util.RandomAccess;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* JSON数组<br>
|
|
|
|
|
* JSON数组是表示中括号括住的数据表现形式<br>
|
|
|
|
|
* 对应的JSON字符串格格式例如:
|
2021-02-03 13:33:31 +08:00
|
|
|
|
*
|
2021-01-20 17:10:45 +08:00
|
|
|
|
* <pre>
|
|
|
|
|
* ["a", "b", "c", 12]
|
|
|
|
|
* </pre>
|
2021-02-03 13:33:31 +08:00
|
|
|
|
*
|
2021-01-20 17:10:45 +08:00
|
|
|
|
* @author looly
|
|
|
|
|
*/
|
|
|
|
|
public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, RandomAccess {
|
|
|
|
|
private static final long serialVersionUID = 2664900568717612292L;
|
|
|
|
|
|
2021-05-24 23:52:18 +08:00
|
|
|
|
/**
|
|
|
|
|
* 默认初始大小
|
|
|
|
|
*/
|
2021-01-20 17:10:45 +08:00
|
|
|
|
public static final int DEFAULT_CAPACITY = 10;
|
|
|
|
|
|
2021-05-24 23:52:18 +08:00
|
|
|
|
/**
|
|
|
|
|
* 持有原始数据的List
|
|
|
|
|
*/
|
2022-03-19 16:15:58 +08:00
|
|
|
|
private List<Object> rawList;
|
2021-05-24 23:52:18 +08:00
|
|
|
|
/**
|
|
|
|
|
* 配置项
|
|
|
|
|
*/
|
2021-01-20 17:10:45 +08:00
|
|
|
|
private final JSONConfig config;
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------- Constructor start
|
2021-05-24 23:52:18 +08:00
|
|
|
|
|
2021-01-20 17:10:45 +08:00
|
|
|
|
/**
|
|
|
|
|
* 构造<br>
|
|
|
|
|
* 默认使用{@link ArrayList} 实现
|
|
|
|
|
*/
|
|
|
|
|
public JSONArray() {
|
|
|
|
|
this(DEFAULT_CAPACITY);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 构造<br>
|
|
|
|
|
* 默认使用{@link ArrayList} 实现
|
2021-02-03 13:33:31 +08:00
|
|
|
|
*
|
2021-01-20 17:10:45 +08:00
|
|
|
|
* @param initialCapacity 初始大小
|
|
|
|
|
* @since 3.2.2
|
|
|
|
|
*/
|
|
|
|
|
public JSONArray(int initialCapacity) {
|
|
|
|
|
this(initialCapacity, JSONConfig.create());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 构造<br>
|
|
|
|
|
* 默认使用{@link ArrayList} 实现
|
2021-02-03 13:33:31 +08:00
|
|
|
|
*
|
2021-01-20 17:10:45 +08:00
|
|
|
|
* @param config JSON配置项
|
|
|
|
|
* @since 4.6.5
|
|
|
|
|
*/
|
|
|
|
|
public JSONArray(JSONConfig config) {
|
|
|
|
|
this(DEFAULT_CAPACITY, config);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 构造<br>
|
|
|
|
|
* 默认使用{@link ArrayList} 实现
|
2021-02-03 13:33:31 +08:00
|
|
|
|
*
|
2021-01-20 17:10:45 +08:00
|
|
|
|
* @param initialCapacity 初始大小
|
2021-05-24 23:52:18 +08:00
|
|
|
|
* @param config JSON配置项
|
2021-01-20 17:10:45 +08:00
|
|
|
|
* @since 4.1.19
|
|
|
|
|
*/
|
|
|
|
|
public JSONArray(int initialCapacity, JSONConfig config) {
|
|
|
|
|
this.rawList = new ArrayList<>(initialCapacity);
|
2022-01-13 14:58:20 +08:00
|
|
|
|
this.config = ObjectUtil.defaultIfNull(config, JSONConfig::create);
|
2021-01-20 17:10:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 构造<br>
|
|
|
|
|
* 将参数数组中的元素转换为JSON对应的对象加入到JSONArray中
|
2021-02-03 13:33:31 +08:00
|
|
|
|
*
|
2021-01-20 17:10:45 +08:00
|
|
|
|
* @param list 初始化的JSON数组
|
|
|
|
|
*/
|
|
|
|
|
public JSONArray(Iterable<Object> list) {
|
|
|
|
|
this();
|
|
|
|
|
for (Object o : list) {
|
|
|
|
|
this.add(o);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 构造<br>
|
|
|
|
|
* 将参数数组中的元素转换为JSON对应的对象加入到JSONArray中
|
2021-02-03 13:33:31 +08:00
|
|
|
|
*
|
2021-01-20 17:10:45 +08:00
|
|
|
|
* @param list 初始化的JSON数组
|
|
|
|
|
*/
|
|
|
|
|
public JSONArray(Collection<Object> list) {
|
|
|
|
|
this(list.size());
|
|
|
|
|
this.addAll(list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 使用 {@link JSONTokener} 做为参数构造
|
|
|
|
|
*
|
|
|
|
|
* @param x A {@link JSONTokener}
|
|
|
|
|
* @throws JSONException If there is a syntax error.
|
|
|
|
|
*/
|
|
|
|
|
public JSONArray(JSONTokener x) throws JSONException {
|
|
|
|
|
this();
|
|
|
|
|
init(x);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 从String构造(JSONArray字符串)
|
|
|
|
|
*
|
|
|
|
|
* @param source JSON数组字符串
|
|
|
|
|
* @throws JSONException If there is a syntax error.
|
|
|
|
|
*/
|
|
|
|
|
public JSONArray(CharSequence source) throws JSONException {
|
|
|
|
|
this();
|
|
|
|
|
init(source);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 从对象构造,忽略{@code null}的值<br>
|
|
|
|
|
* 支持以下类型的参数:
|
2021-02-03 13:33:31 +08:00
|
|
|
|
*
|
2021-01-20 17:10:45 +08:00
|
|
|
|
* <pre>
|
|
|
|
|
* 1. 数组
|
|
|
|
|
* 2. {@link Iterable}对象
|
|
|
|
|
* 3. JSON数组字符串
|
|
|
|
|
* </pre>
|
|
|
|
|
*
|
|
|
|
|
* @param object 数组或集合或JSON数组字符串
|
|
|
|
|
* @throws JSONException 非数组或集合
|
|
|
|
|
*/
|
|
|
|
|
public JSONArray(Object object) throws JSONException {
|
|
|
|
|
this(object, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 从对象构造<br>
|
|
|
|
|
* 支持以下类型的参数:
|
2021-02-03 13:33:31 +08:00
|
|
|
|
*
|
2021-01-20 17:10:45 +08:00
|
|
|
|
* <pre>
|
|
|
|
|
* 1. 数组
|
|
|
|
|
* 2. {@link Iterable}对象
|
|
|
|
|
* 3. JSON数组字符串
|
|
|
|
|
* </pre>
|
|
|
|
|
*
|
2021-05-24 23:52:18 +08:00
|
|
|
|
* @param object 数组或集合或JSON数组字符串
|
2021-01-20 17:10:45 +08:00
|
|
|
|
* @param ignoreNullValue 是否忽略空值
|
|
|
|
|
* @throws JSONException 非数组或集合
|
|
|
|
|
*/
|
|
|
|
|
public JSONArray(Object object, boolean ignoreNullValue) throws JSONException {
|
|
|
|
|
this(object, JSONConfig.create().setIgnoreNullValue(ignoreNullValue));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 从对象构造<br>
|
|
|
|
|
* 支持以下类型的参数:
|
2021-02-03 13:33:31 +08:00
|
|
|
|
*
|
2021-01-20 17:10:45 +08:00
|
|
|
|
* <pre>
|
|
|
|
|
* 1. 数组
|
|
|
|
|
* 2. {@link Iterable}对象
|
|
|
|
|
* 3. JSON数组字符串
|
|
|
|
|
* </pre>
|
|
|
|
|
*
|
2021-05-24 23:52:18 +08:00
|
|
|
|
* @param object 数组或集合或JSON数组字符串
|
2021-01-20 17:10:45 +08:00
|
|
|
|
* @param jsonConfig JSON选项
|
|
|
|
|
* @throws JSONException 非数组或集合
|
|
|
|
|
* @since 4.6.5
|
|
|
|
|
*/
|
|
|
|
|
public JSONArray(Object object, JSONConfig jsonConfig) throws JSONException {
|
|
|
|
|
this(DEFAULT_CAPACITY, jsonConfig);
|
|
|
|
|
init(object);
|
|
|
|
|
}
|
2022-03-31 18:01:55 +08:00
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------- Constructor end
|
2021-01-20 17:10:45 +08:00
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public JSONConfig getConfig() {
|
|
|
|
|
return this.config;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 设置转为字符串时的日期格式,默认为时间戳(null值)
|
2021-02-03 13:33:31 +08:00
|
|
|
|
*
|
2021-01-20 17:10:45 +08:00
|
|
|
|
* @param format 格式,null表示使用时间戳
|
|
|
|
|
* @return this
|
|
|
|
|
* @since 4.1.19
|
|
|
|
|
*/
|
|
|
|
|
public JSONArray setDateFormat(String format) {
|
|
|
|
|
this.config.setDateFormat(format);
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* JSONArray转为以{@code separator}为分界符的字符串
|
|
|
|
|
*
|
|
|
|
|
* @param separator 分界符
|
|
|
|
|
* @return a string.
|
|
|
|
|
* @throws JSONException If the array contains an invalid number.
|
|
|
|
|
*/
|
|
|
|
|
public String join(String separator) throws JSONException {
|
2021-06-26 23:49:43 +08:00
|
|
|
|
return StrJoiner.of(separator)
|
|
|
|
|
.append(this, InternalJSONUtil::valueToString).toString();
|
2021-01-20 17:10:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Object get(int index) {
|
|
|
|
|
return this.rawList.get(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Object getObj(Integer index, Object defaultValue) {
|
|
|
|
|
return (index < 0 || index >= this.size()) ? defaultValue : this.rawList.get(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Object getByPath(String expression) {
|
|
|
|
|
return BeanPath.create(expression).get(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public <T> T getByPath(String expression, Class<T> resultType) {
|
2022-02-13 19:26:42 +08:00
|
|
|
|
return JSONConverter.jsonConvert(resultType, getByPath(expression), true);
|
2021-01-20 17:10:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void putByPath(String expression, Object value) {
|
|
|
|
|
BeanPath.create(expression).set(this, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Append an object value. This increases the array's length by one. <br>
|
|
|
|
|
* 加入元素,数组长度+1,等同于 {@link JSONArray#add(Object)}
|
|
|
|
|
*
|
|
|
|
|
* @param value 值,可以是: Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the JSONNull.NULL。
|
|
|
|
|
* @return this.
|
|
|
|
|
* @see #set(Object)
|
|
|
|
|
*/
|
|
|
|
|
public JSONArray put(Object value) {
|
|
|
|
|
return set(value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Append an object value. This increases the array's length by one. <br>
|
|
|
|
|
* 加入元素,数组长度+1,等同于 {@link JSONArray#add(Object)}
|
|
|
|
|
*
|
|
|
|
|
* @param value 值,可以是: Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the JSONNull.NULL。
|
|
|
|
|
* @return this.
|
|
|
|
|
* @since 5.2.5
|
|
|
|
|
*/
|
|
|
|
|
public JSONArray set(Object value) {
|
|
|
|
|
this.add(value);
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 加入或者替换JSONArray中指定Index的值,如果index大于JSONArray的长度,将在指定index设置值,之前的位置填充JSONNull.Null
|
|
|
|
|
*
|
|
|
|
|
* @param index 位置
|
|
|
|
|
* @param value 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL.
|
|
|
|
|
* @return this.
|
|
|
|
|
* @throws JSONException index < 0 或者非有限的数字
|
2021-05-24 23:52:18 +08:00
|
|
|
|
* @see #set(int, Object)
|
2021-01-20 17:10:45 +08:00
|
|
|
|
*/
|
|
|
|
|
public JSONArray put(int index, Object value) throws JSONException {
|
2021-05-24 23:52:18 +08:00
|
|
|
|
this.set(index, value);
|
2021-01-20 17:10:45 +08:00
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-31 18:01:55 +08:00
|
|
|
|
@Override
|
|
|
|
|
public <T> T toBean(Type type) {
|
|
|
|
|
return JSON.super.toBean(type, config.isIgnoreError());
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-20 17:10:45 +08:00
|
|
|
|
/**
|
|
|
|
|
* 根据给定名列表,与其位置对应的值组成JSONObject
|
|
|
|
|
*
|
|
|
|
|
* @param names 名列表,位置与JSONArray中的值位置对应
|
|
|
|
|
* @return A JSONObject,无名或值返回null
|
|
|
|
|
* @throws JSONException 如果任何一个名为null
|
|
|
|
|
*/
|
|
|
|
|
public JSONObject toJSONObject(JSONArray names) throws JSONException {
|
|
|
|
|
if (names == null || names.size() == 0 || this.size() == 0) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
final JSONObject jo = new JSONObject(this.config);
|
|
|
|
|
for (int i = 0; i < names.size(); i += 1) {
|
|
|
|
|
jo.set(names.getStr(i), this.getObj(i));
|
|
|
|
|
}
|
|
|
|
|
return jo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public int hashCode() {
|
|
|
|
|
final int prime = 31;
|
|
|
|
|
int result = 1;
|
|
|
|
|
result = prime * result + ((rawList == null) ? 0 : rawList.hashCode());
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean equals(Object obj) {
|
|
|
|
|
if (this == obj) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
if (obj == null) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (getClass() != obj.getClass()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
final JSONArray other = (JSONArray) obj;
|
|
|
|
|
if (rawList == null) {
|
|
|
|
|
return other.rawList == null;
|
|
|
|
|
} else {
|
|
|
|
|
return rawList.equals(other.rawList);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Iterator<Object> iterator() {
|
|
|
|
|
return rawList.iterator();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 当此JSON列表的每个元素都是一个JSONObject时,可以调用此方法返回一个Iterable,便于使用foreach语法遍历
|
2021-02-03 13:33:31 +08:00
|
|
|
|
*
|
2021-01-20 17:10:45 +08:00
|
|
|
|
* @return Iterable
|
|
|
|
|
* @since 4.0.12
|
|
|
|
|
*/
|
|
|
|
|
public Iterable<JSONObject> jsonIter() {
|
|
|
|
|
return new JSONObjectIter(iterator());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public int size() {
|
|
|
|
|
return rawList.size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean isEmpty() {
|
|
|
|
|
return rawList.isEmpty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean contains(Object o) {
|
|
|
|
|
return rawList.contains(o);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Object[] toArray() {
|
|
|
|
|
return rawList.toArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@SuppressWarnings({"unchecked"})
|
|
|
|
|
public <T> T[] toArray(T[] a) {
|
|
|
|
|
return (T[]) JSONConverter.toArray(this, a.getClass().getComponentType());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean add(Object e) {
|
|
|
|
|
return this.rawList.add(JSONUtil.wrap(e, this.config));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Object remove(int index) {
|
|
|
|
|
return index >= 0 && index < this.size() ? this.rawList.remove(index) : null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean remove(Object o) {
|
|
|
|
|
return rawList.remove(o);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("NullableProblems")
|
|
|
|
|
@Override
|
|
|
|
|
public boolean containsAll(Collection<?> c) {
|
|
|
|
|
return rawList.containsAll(c);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("NullableProblems")
|
|
|
|
|
@Override
|
|
|
|
|
public boolean addAll(Collection<?> c) {
|
|
|
|
|
if (CollUtil.isEmpty(c)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
for (Object obj : c) {
|
|
|
|
|
this.add(obj);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("NullableProblems")
|
|
|
|
|
@Override
|
|
|
|
|
public boolean addAll(int index, Collection<?> c) {
|
|
|
|
|
if (CollUtil.isEmpty(c)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
final ArrayList<Object> list = new ArrayList<>(c.size());
|
|
|
|
|
for (Object object : c) {
|
|
|
|
|
list.add(JSONUtil.wrap(object, this.config));
|
|
|
|
|
}
|
|
|
|
|
return rawList.addAll(index, list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("NullableProblems")
|
|
|
|
|
@Override
|
|
|
|
|
public boolean removeAll(Collection<?> c) {
|
|
|
|
|
return this.rawList.removeAll(c);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("NullableProblems")
|
|
|
|
|
@Override
|
|
|
|
|
public boolean retainAll(Collection<?> c) {
|
|
|
|
|
return this.rawList.retainAll(c);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void clear() {
|
|
|
|
|
this.rawList.clear();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-24 23:52:18 +08:00
|
|
|
|
/**
|
|
|
|
|
* 加入或者替换JSONArray中指定Index的值,如果index大于JSONArray的长度,将在指定index设置值,之前的位置填充JSONNull.Null
|
|
|
|
|
*
|
2021-10-30 02:23:28 +08:00
|
|
|
|
* @param index 位置
|
2021-05-24 23:52:18 +08:00
|
|
|
|
* @param element 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL.
|
|
|
|
|
* @return 替换的值,即之前的值
|
|
|
|
|
*/
|
2021-01-20 17:10:45 +08:00
|
|
|
|
@Override
|
|
|
|
|
public Object set(int index, Object element) {
|
2021-10-30 02:23:28 +08:00
|
|
|
|
if (index >= size()) {
|
2021-06-15 17:01:27 +08:00
|
|
|
|
add(index, element);
|
|
|
|
|
}
|
2021-01-20 17:10:45 +08:00
|
|
|
|
return this.rawList.set(index, JSONUtil.wrap(element, this.config));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void add(int index, Object element) {
|
|
|
|
|
if (index < 0) {
|
|
|
|
|
throw new JSONException("JSONArray[{}] not found.", index);
|
|
|
|
|
}
|
|
|
|
|
if (index < this.size()) {
|
|
|
|
|
InternalJSONUtil.testValidity(element);
|
|
|
|
|
this.rawList.add(index, JSONUtil.wrap(element, this.config));
|
|
|
|
|
} else {
|
|
|
|
|
while (index != this.size()) {
|
|
|
|
|
this.add(JSONNull.NULL);
|
|
|
|
|
}
|
|
|
|
|
this.set(element);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public int indexOf(Object o) {
|
|
|
|
|
return this.rawList.indexOf(o);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public int lastIndexOf(Object o) {
|
|
|
|
|
return this.rawList.lastIndexOf(o);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public ListIterator<Object> listIterator() {
|
|
|
|
|
return this.rawList.listIterator();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public ListIterator<Object> listIterator(int index) {
|
|
|
|
|
return this.rawList.listIterator(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<Object> subList(int fromIndex, int toIndex) {
|
|
|
|
|
return this.rawList.subList(fromIndex, toIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 转为Bean数组
|
2021-02-03 13:33:31 +08:00
|
|
|
|
*
|
2021-01-20 17:10:45 +08:00
|
|
|
|
* @param arrayClass 数组元素类型
|
|
|
|
|
* @return 实体类对象
|
|
|
|
|
*/
|
|
|
|
|
public Object toArray(Class<?> arrayClass) {
|
|
|
|
|
return JSONConverter.toArray(this, arrayClass);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 转为{@link ArrayList}
|
2021-02-03 13:33:31 +08:00
|
|
|
|
*
|
2021-05-24 23:52:18 +08:00
|
|
|
|
* @param <T> 元素类型
|
2021-01-20 17:10:45 +08:00
|
|
|
|
* @param elementType 元素类型
|
|
|
|
|
* @return {@link ArrayList}
|
|
|
|
|
* @since 3.0.8
|
|
|
|
|
*/
|
|
|
|
|
public <T> List<T> toList(Class<T> elementType) {
|
|
|
|
|
return JSONConverter.toList(this, elementType);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 转为JSON字符串,无缩进
|
|
|
|
|
*
|
|
|
|
|
* @return JSONArray字符串
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public String toString() {
|
|
|
|
|
return this.toJSONString(0);
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-15 01:27:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* 返回JSON字符串<br>
|
|
|
|
|
* 支持过滤器,即选择哪些字段或值不写出
|
|
|
|
|
*
|
|
|
|
|
* @param indentFactor 每层缩进空格数
|
2021-10-30 02:23:28 +08:00
|
|
|
|
* @param filter 过滤器,可以修改值,key(index)无法修改
|
2021-10-15 01:27:16 +08:00
|
|
|
|
* @return JSON字符串
|
|
|
|
|
* @since 5.7.15
|
|
|
|
|
*/
|
2021-10-30 02:23:28 +08:00
|
|
|
|
public String toJSONString(int indentFactor, Filter<MutablePair<Integer, Object>> filter) {
|
2021-10-15 01:27:16 +08:00
|
|
|
|
final StringWriter sw = new StringWriter();
|
|
|
|
|
synchronized (sw.getBuffer()) {
|
|
|
|
|
return this.write(sw, indentFactor, 0, filter).toString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-20 17:10:45 +08:00
|
|
|
|
@Override
|
|
|
|
|
public Writer write(Writer writer, int indentFactor, int indent) throws JSONException {
|
2021-10-15 01:27:16 +08:00
|
|
|
|
return write(writer, indentFactor, indent, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 将JSON内容写入Writer<br>
|
|
|
|
|
* 支持过滤器,即选择哪些字段或值不写出
|
|
|
|
|
*
|
|
|
|
|
* @param writer writer
|
|
|
|
|
* @param indentFactor 缩进因子,定义每一级别增加的缩进量
|
|
|
|
|
* @param indent 本级别缩进量
|
2021-10-30 02:23:28 +08:00
|
|
|
|
* @param filter 过滤器,可以修改值,key(index)无法修改
|
2021-10-15 01:27:16 +08:00
|
|
|
|
* @return Writer
|
|
|
|
|
* @throws JSONException JSON相关异常
|
|
|
|
|
* @since 5.7.15
|
|
|
|
|
*/
|
2021-10-30 02:23:28 +08:00
|
|
|
|
public Writer write(Writer writer, int indentFactor, int indent, Filter<MutablePair<Integer, Object>> filter) throws JSONException {
|
2021-06-26 23:49:43 +08:00
|
|
|
|
final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config)
|
|
|
|
|
.beginArray();
|
2021-10-15 01:27:16 +08:00
|
|
|
|
|
2021-10-30 02:23:28 +08:00
|
|
|
|
CollUtil.forEach(this, (value, index) -> {
|
|
|
|
|
final MutablePair<Integer, Object> pair = new MutablePair<>(index, value);
|
|
|
|
|
if (null == filter || filter.accept(pair)) {
|
|
|
|
|
jsonWriter.writeValue(pair.getValue());
|
2021-10-15 01:27:16 +08:00
|
|
|
|
}
|
|
|
|
|
});
|
2021-06-26 16:56:47 +08:00
|
|
|
|
jsonWriter.end();
|
2021-06-26 23:49:43 +08:00
|
|
|
|
// 此处不关闭Writer,考虑writer后续还需要填内容
|
2021-01-20 17:10:45 +08:00
|
|
|
|
return writer;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-19 16:15:58 +08:00
|
|
|
|
@Override
|
|
|
|
|
public Object clone() throws CloneNotSupportedException {
|
|
|
|
|
final JSONArray clone = (JSONArray) super.clone();
|
|
|
|
|
clone.rawList = ObjectUtil.clone(this.rawList);
|
|
|
|
|
return clone;
|
|
|
|
|
}
|
2021-06-26 16:56:47 +08:00
|
|
|
|
// ------------------------------------------------------------------------------------------------- Private method start
|
2021-10-30 02:23:28 +08:00
|
|
|
|
|
2021-01-20 17:10:45 +08:00
|
|
|
|
/**
|
|
|
|
|
* 初始化
|
2021-02-03 13:33:31 +08:00
|
|
|
|
*
|
2021-01-20 17:10:45 +08:00
|
|
|
|
* @param source 数组或集合或JSON数组字符串
|
|
|
|
|
* @throws JSONException 非数组或集合
|
|
|
|
|
*/
|
2021-05-24 23:52:18 +08:00
|
|
|
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
2021-01-20 17:10:45 +08:00
|
|
|
|
private void init(Object source) throws JSONException {
|
|
|
|
|
if (null == source) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final JSONSerializer serializer = GlobalSerializeMapping.getSerializer(source.getClass());
|
|
|
|
|
if (null != serializer && JSONArray.class.equals(TypeUtil.getTypeArgument(serializer.getClass()))) {
|
|
|
|
|
// 自定义序列化
|
|
|
|
|
serializer.serialize(this, source);
|
|
|
|
|
} else if (source instanceof CharSequence) {
|
|
|
|
|
// JSON字符串
|
|
|
|
|
init((CharSequence) source);
|
2021-05-24 23:52:18 +08:00
|
|
|
|
} else if (source instanceof JSONTokener) {
|
2021-01-20 17:10:45 +08:00
|
|
|
|
init((JSONTokener) source);
|
|
|
|
|
} else {
|
|
|
|
|
Iterator<?> iter;
|
|
|
|
|
if (ArrayUtil.isArray(source)) {// 数组
|
|
|
|
|
iter = new ArrayIter<>(source);
|
|
|
|
|
} else if (source instanceof Iterator<?>) {// Iterator
|
|
|
|
|
iter = ((Iterator<?>) source);
|
|
|
|
|
} else if (source instanceof Iterable<?>) {// Iterable
|
|
|
|
|
iter = ((Iterable<?>) source).iterator();
|
|
|
|
|
} else {
|
|
|
|
|
throw new JSONException("JSONArray initial value should be a string or collection or array.");
|
|
|
|
|
}
|
2021-02-03 13:33:31 +08:00
|
|
|
|
|
|
|
|
|
Object next;
|
2021-01-20 17:10:45 +08:00
|
|
|
|
while (iter.hasNext()) {
|
2021-02-03 13:33:31 +08:00
|
|
|
|
next = iter.next();
|
|
|
|
|
// 检查循环引用
|
2021-05-24 23:52:18 +08:00
|
|
|
|
if (next != source) {
|
2021-02-03 13:33:31 +08:00
|
|
|
|
this.add(next);
|
|
|
|
|
}
|
2021-01-20 17:10:45 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 初始化
|
2021-02-03 13:33:31 +08:00
|
|
|
|
*
|
2021-01-20 17:10:45 +08:00
|
|
|
|
* @param source JSON字符串
|
|
|
|
|
*/
|
|
|
|
|
private void init(CharSequence source) {
|
|
|
|
|
if (null != source) {
|
|
|
|
|
init(new JSONTokener(StrUtil.trim(source), this.config));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 初始化
|
2021-02-03 13:33:31 +08:00
|
|
|
|
*
|
2021-01-20 17:10:45 +08:00
|
|
|
|
* @param x {@link JSONTokener}
|
|
|
|
|
*/
|
|
|
|
|
private void init(JSONTokener x) {
|
|
|
|
|
if (x.nextClean() != '[') {
|
|
|
|
|
throw x.syntaxError("A JSONArray text must start with '['");
|
|
|
|
|
}
|
|
|
|
|
if (x.nextClean() != ']') {
|
|
|
|
|
x.back();
|
2021-05-24 23:52:18 +08:00
|
|
|
|
for (; ; ) {
|
2021-01-20 17:10:45 +08:00
|
|
|
|
if (x.nextClean() == ',') {
|
|
|
|
|
x.back();
|
|
|
|
|
this.rawList.add(JSONNull.NULL);
|
|
|
|
|
} else {
|
|
|
|
|
x.back();
|
|
|
|
|
this.rawList.add(x.nextValue());
|
|
|
|
|
}
|
|
|
|
|
switch (x.nextClean()) {
|
2021-05-24 23:52:18 +08:00
|
|
|
|
case ',':
|
|
|
|
|
if (x.nextClean() == ']') {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
x.back();
|
|
|
|
|
break;
|
|
|
|
|
case ']':
|
2021-01-20 17:10:45 +08:00
|
|
|
|
return;
|
2021-05-24 23:52:18 +08:00
|
|
|
|
default:
|
|
|
|
|
throw x.syntaxError("Expected a ',' or ']'");
|
2021-01-20 17:10:45 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// ------------------------------------------------------------------------------------------------- Private method end
|
|
|
|
|
}
|