diff --git a/CHANGELOG.md b/CHANGELOG.md index 58fd22d36..83b637af7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,10 +14,13 @@ * 【core 】 PhoneUtil增加中国澳门和中国台湾手机号校检方法(pr#331@Gitee) * 【db 】 分页查询,自定义sql查询,添加参数(pr#332@Gitee) * 【core 】 IdCardUtil.isValidCard增加非空判断 +* 【json 】 JSONObject构造增加SortedMap判断(pr#333@Gitee) +* 【core 】 Tuple增加部分方法(pr#333@Gitee) ### 🐞Bug修复 * 【core 】 修复XmlUtil中omitXmlDeclaration参数无效问题(issue#1581@Github) * 【core 】 修复NumberUtil.decimalFormat参数传错的问题(issue#I3SDS3@Gitee) +* 【json 】 修复JSONArray.put方法不能覆盖值的问题 ------------------------------------------------------------------------------------------------------------- # 5.6.5 (2021-05-08) diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/Tuple.java b/hutool-core/src/main/java/cn/hutool/core/lang/Tuple.java index 2c522ef5c..c845e9b3a 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/Tuple.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/Tuple.java @@ -2,52 +2,71 @@ package cn.hutool.core.lang; import cn.hutool.core.clone.CloneSupport; import cn.hutool.core.collection.ArrayIter; +import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.util.ArrayUtil; import java.io.Serializable; import java.util.Arrays; import java.util.Iterator; +import java.util.List; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; /** - * 不可变数组类型,用于多值返回
+ * 不可变数组类型(元组),用于多值返回
* 多值可以支持每个元素值类型不同 - * - * @author Looly * + * @author Looly */ -public class Tuple extends CloneSupport implements Iterable, Serializable{ +public class Tuple extends CloneSupport implements Iterable, Serializable { private static final long serialVersionUID = -7689304393482182157L; - + private final Object[] members; private int hashCode; private boolean cacheHash; - + /** * 构造 + * * @param members 成员数组 */ public Tuple(Object... members) { this.members = members; } - + /** * 获取指定位置元素 - * @param 返回对象类型 + * + * @param 返回对象类型 * @param index 位置 * @return 元素 */ @SuppressWarnings("unchecked") - public T get(int index){ + public T get(int index) { return (T) members[index]; } - + /** * 获得所有元素 + * * @return 获得所有元素 */ - public Object[] getMembers(){ + public Object[] getMembers() { return this.members; } + /** + * 将元组转换成列表 + * + * @return 转换得到的列表 + * @since 5.6.6 + */ + public final List toList() { + return ListUtil.toList(this.members); + } + /** * 缓存Hash值,当为true时,此对象的hash值只被计算一次,常用于Tuple中的值不变时使用。 * 注意:当为true时,member变更对象后,hash值不会变更。 @@ -56,20 +75,73 @@ public class Tuple extends CloneSupport implements Iterable, Seri * @return this * @since 5.2.1 */ - public Tuple setCacheHash(boolean cacheHash){ + public Tuple setCacheHash(boolean cacheHash) { this.cacheHash = cacheHash; return this; } - + + /** + * 得到元组的大小 + * + * @return 元组的大小 + * @since 5.6.6 + */ + public int size() { + return this.members.length; + } + + /** + * 判断元组中是否包含某元素 + * + * @param value 需要判定的元素 + * @return 是否包含 + * @since 5.6.6 + */ + public boolean contains(Object value) { + return ArrayUtil.contains(this.members, value); + } + + /** + * 将元组转成流 + * + * @return 流 + * @since 5.6.6 + */ + public final Stream stream() { + return Arrays.stream(this.members); + } + + /** + * 将元组转成并行流 + * + * @return 流 + * @since 5.6.6 + */ + public final Stream parallelStream() { + return StreamSupport.stream(spliterator(), true); + } + + /** + * 截取元组指定部分 + * + * @param start 起始位置(包括) + * @param end 终止位置(不包括) + * @return 截取得到的元组 + * @since 5.6.6 + */ + public final Tuple sub(final int start, final int end) { + return new Tuple(ArrayUtil.sub(this.members, start, end)); + } + @Override public int hashCode() { - if(this.cacheHash && 0 != this.hashCode){ + if (this.cacheHash && 0 != this.hashCode) { return this.hashCode; } final int prime = 31; int result = 1; result = prime * result + Arrays.deepHashCode(members); - if(this.cacheHash){ + if (this.cacheHash) { this.hashCode = result; } return result; @@ -95,9 +167,13 @@ public class Tuple extends CloneSupport implements Iterable, Seri return Arrays.toString(members); } - @SuppressWarnings("NullableProblems") @Override public Iterator iterator() { return new ArrayIter<>(members); } + + @Override + public final Spliterator spliterator() { + return Spliterators.spliterator(this.members, Spliterator.ORDERED); + } } diff --git a/hutool-json/src/main/java/cn/hutool/json/JSONArray.java b/hutool-json/src/main/java/cn/hutool/json/JSONArray.java index 393cc0c61..5da4ab9a3 100644 --- a/hutool-json/src/main/java/cn/hutool/json/JSONArray.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONArray.java @@ -36,15 +36,22 @@ import static cn.hutool.json.JSONConverter.jsonConvert; public class JSONArray implements JSON, JSONGetter, List, RandomAccess { private static final long serialVersionUID = 2664900568717612292L; - /** 默认初始大小 */ + /** + * 默认初始大小 + */ public static final int DEFAULT_CAPACITY = 10; - /** 持有原始数据的List */ + /** + * 持有原始数据的List + */ private final List rawList; - /** 配置项 */ + /** + * 配置项 + */ private final JSONConfig config; // -------------------------------------------------------------------------------------------------------------------- Constructor start + /** * 构造
* 默认使用{@link ArrayList} 实现 @@ -80,7 +87,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando * 默认使用{@link ArrayList} 实现 * * @param initialCapacity 初始大小 - * @param config JSON配置项 + * @param config JSON配置项 * @since 4.1.19 */ public JSONArray(int initialCapacity, JSONConfig config) { @@ -161,7 +168,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando * 3. JSON数组字符串 * * - * @param object 数组或集合或JSON数组字符串 + * @param object 数组或集合或JSON数组字符串 * @param ignoreNullValue 是否忽略空值 * @throws JSONException 非数组或集合 */ @@ -179,7 +186,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando * 3. JSON数组字符串 * * - * @param object 数组或集合或JSON数组字符串 + * @param object 数组或集合或JSON数组字符串 * @param jsonConfig JSON选项 * @throws JSONException 非数组或集合 * @since 4.6.5 @@ -284,9 +291,10 @@ public class JSONArray implements JSON, JSONGetter, List, Rando * @param value 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL. * @return this. * @throws JSONException index < 0 或者非有限的数字 + * @see #set(int, Object) */ public JSONArray put(int index, Object value) throws JSONException { - this.add(index, value); + this.set(index, value); return this; } @@ -335,7 +343,6 @@ public class JSONArray implements JSON, JSONGetter, List, Rando } } - @SuppressWarnings("NullableProblems") @Override public Iterator iterator() { return rawList.iterator(); @@ -441,6 +448,13 @@ public class JSONArray implements JSON, JSONGetter, List, Rando } + /** + * 加入或者替换JSONArray中指定Index的值,如果index大于JSONArray的长度,将在指定index设置值,之前的位置填充JSONNull.Null + * + * @param index 位置 + * @param element 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL. + * @return 替换的值,即之前的值 + */ @Override public Object set(int index, Object element) { return this.rawList.set(index, JSONUtil.wrap(element, this.config)); @@ -473,19 +487,16 @@ public class JSONArray implements JSON, JSONGetter, List, Rando return this.rawList.lastIndexOf(o); } - @SuppressWarnings("NullableProblems") @Override public ListIterator listIterator() { return this.rawList.listIterator(); } - @SuppressWarnings("NullableProblems") @Override public ListIterator listIterator(int index) { return this.rawList.listIterator(index); } - @SuppressWarnings("NullableProblems") @Override public List subList(int fromIndex, int toIndex) { return this.rawList.subList(fromIndex, toIndex); @@ -504,7 +515,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 转为{@link ArrayList} * - * @param 元素类型 + * @param 元素类型 * @param elementType 元素类型 * @return {@link ArrayList} * @since 3.0.8 @@ -537,9 +548,9 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 将JSON内容写入Writer * - * @param writer writer + * @param writer writer * @param indentFactor 缩进因子,定义每一级别增加的缩进量 - * @param indent 本级别缩进量 + * @param indent 本级别缩进量 * @return Writer * @throws IOException IO相关异常 */ @@ -579,7 +590,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando * @param source 数组或集合或JSON数组字符串 * @throws JSONException 非数组或集合 */ - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings({"rawtypes", "unchecked"}) private void init(Object source) throws JSONException { if (null == source) { return; @@ -592,7 +603,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando } else if (source instanceof CharSequence) { // JSON字符串 init((CharSequence) source); - }else if (source instanceof JSONTokener) { + } else if (source instanceof JSONTokener) { init((JSONTokener) source); } else { Iterator iter; @@ -610,7 +621,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando while (iter.hasNext()) { next = iter.next(); // 检查循环引用 - if(next != source){ + if (next != source) { this.add(next); } } @@ -639,7 +650,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando } if (x.nextClean() != ']') { x.back(); - for (;;) { + for (; ; ) { if (x.nextClean() == ',') { x.back(); this.rawList.add(JSONNull.NULL); @@ -648,16 +659,16 @@ public class JSONArray implements JSON, JSONGetter, List, Rando this.rawList.add(x.nextValue()); } switch (x.nextClean()) { - case ',': - if (x.nextClean() == ']') { + case ',': + if (x.nextClean() == ']') { + return; + } + x.back(); + break; + case ']': return; - } - x.back(); - break; - case ']': - return; - default: - throw x.syntaxError("Expected a ',' or ']'"); + default: + throw x.syntaxError("Expected a ',' or ']'"); } } } diff --git a/hutool-json/src/main/java/cn/hutool/json/JSONObject.java b/hutool-json/src/main/java/cn/hutool/json/JSONObject.java index 18d4a9d08..0258fa9fe 100644 --- a/hutool-json/src/main/java/cn/hutool/json/JSONObject.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONObject.java @@ -25,10 +25,10 @@ import java.math.BigInteger; import java.util.Collection; import java.util.Enumeration; import java.util.LinkedHashMap; -import java.util.TreeMap; import java.util.Map; import java.util.ResourceBundle; import java.util.Set; +import java.util.SortedMap; /** * JSON对象
@@ -158,7 +158,7 @@ public class JSONObject implements JSON, JSONGetter, Map * @since 3.0.9 */ public JSONObject(Object source, boolean ignoreNullValue) { - this(source, ignoreNullValue, (source instanceof LinkedHashMap) || (source instanceof TreeMap)); + this(source, ignoreNullValue, (source instanceof LinkedHashMap) || (source instanceof SortedMap)); } /**