add methods

This commit is contained in:
Looly 2021-05-24 23:52:18 +08:00
parent 97f5e2bfa7
commit edd0449187
4 changed files with 135 additions and 45 deletions

View File

@ -14,10 +14,13 @@
* 【core 】 PhoneUtil增加中国澳门和中国台湾手机号校检方法pr#331@Gitee * 【core 】 PhoneUtil增加中国澳门和中国台湾手机号校检方法pr#331@Gitee
* 【db 】 分页查询自定义sql查询添加参数pr#332@Gitee * 【db 】 分页查询自定义sql查询添加参数pr#332@Gitee
* 【core 】 IdCardUtil.isValidCard增加非空判断 * 【core 】 IdCardUtil.isValidCard增加非空判断
* 【json 】 JSONObject构造增加SortedMap判断pr#333@Gitee
* 【core 】 Tuple增加部分方法pr#333@Gitee
### 🐞Bug修复 ### 🐞Bug修复
* 【core 】 修复XmlUtil中omitXmlDeclaration参数无效问题issue#1581@Github * 【core 】 修复XmlUtil中omitXmlDeclaration参数无效问题issue#1581@Github
* 【core 】 修复NumberUtil.decimalFormat参数传错的问题issue#I3SDS3@Gitee * 【core 】 修复NumberUtil.decimalFormat参数传错的问题issue#I3SDS3@Gitee
* 【json 】 修复JSONArray.put方法不能覆盖值的问题
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
# 5.6.5 (2021-05-08) # 5.6.5 (2021-05-08)

View File

@ -2,52 +2,71 @@ package cn.hutool.core.lang;
import cn.hutool.core.clone.CloneSupport; import cn.hutool.core.clone.CloneSupport;
import cn.hutool.core.collection.ArrayIter; import cn.hutool.core.collection.ArrayIter;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ArrayUtil;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator; 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;
/** /**
* 不可变数组类型用于多值返回<br> * 不可变数组类型元组用于多值返回<br>
* 多值可以支持每个元素值类型不同 * 多值可以支持每个元素值类型不同
*
* @author Looly
* *
* @author Looly
*/ */
public class Tuple extends CloneSupport<Tuple> implements Iterable<Object>, Serializable{ public class Tuple extends CloneSupport<Tuple> implements Iterable<Object>, Serializable {
private static final long serialVersionUID = -7689304393482182157L; private static final long serialVersionUID = -7689304393482182157L;
private final Object[] members; private final Object[] members;
private int hashCode; private int hashCode;
private boolean cacheHash; private boolean cacheHash;
/** /**
* 构造 * 构造
*
* @param members 成员数组 * @param members 成员数组
*/ */
public Tuple(Object... members) { public Tuple(Object... members) {
this.members = members; this.members = members;
} }
/** /**
* 获取指定位置元素 * 获取指定位置元素
* @param <T> 返回对象类型 *
* @param <T> 返回对象类型
* @param index 位置 * @param index 位置
* @return 元素 * @return 元素
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> T get(int index){ public <T> T get(int index) {
return (T) members[index]; return (T) members[index];
} }
/** /**
* 获得所有元素 * 获得所有元素
*
* @return 获得所有元素 * @return 获得所有元素
*/ */
public Object[] getMembers(){ public Object[] getMembers() {
return this.members; return this.members;
} }
/**
* 将元组转换成列表
*
* @return 转换得到的列表
* @since 5.6.6
*/
public final List<Object> toList() {
return ListUtil.toList(this.members);
}
/** /**
* 缓存Hash值当为true时此对象的hash值只被计算一次常用于Tuple中的值不变时使用 * 缓存Hash值当为true时此对象的hash值只被计算一次常用于Tuple中的值不变时使用
* 注意当为true时member变更对象后hash值不会变更 * 注意当为true时member变更对象后hash值不会变更
@ -56,20 +75,73 @@ public class Tuple extends CloneSupport<Tuple> implements Iterable<Object>, Seri
* @return this * @return this
* @since 5.2.1 * @since 5.2.1
*/ */
public Tuple setCacheHash(boolean cacheHash){ public Tuple setCacheHash(boolean cacheHash) {
this.cacheHash = cacheHash; this.cacheHash = cacheHash;
return this; 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<Object> stream() {
return Arrays.stream(this.members);
}
/**
* 将元组转成并行流
*
* @return
* @since 5.6.6
*/
public final Stream<Object> 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 @Override
public int hashCode() { public int hashCode() {
if(this.cacheHash && 0 != this.hashCode){ if (this.cacheHash && 0 != this.hashCode) {
return this.hashCode; return this.hashCode;
} }
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result + Arrays.deepHashCode(members); result = prime * result + Arrays.deepHashCode(members);
if(this.cacheHash){ if (this.cacheHash) {
this.hashCode = result; this.hashCode = result;
} }
return result; return result;
@ -95,9 +167,13 @@ public class Tuple extends CloneSupport<Tuple> implements Iterable<Object>, Seri
return Arrays.toString(members); return Arrays.toString(members);
} }
@SuppressWarnings("NullableProblems")
@Override @Override
public Iterator<Object> iterator() { public Iterator<Object> iterator() {
return new ArrayIter<>(members); return new ArrayIter<>(members);
} }
@Override
public final Spliterator<Object> spliterator() {
return Spliterators.spliterator(this.members, Spliterator.ORDERED);
}
} }

View File

@ -36,15 +36,22 @@ import static cn.hutool.json.JSONConverter.jsonConvert;
public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, RandomAccess { public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, RandomAccess {
private static final long serialVersionUID = 2664900568717612292L; private static final long serialVersionUID = 2664900568717612292L;
/** 默认初始大小 */ /**
* 默认初始大小
*/
public static final int DEFAULT_CAPACITY = 10; public static final int DEFAULT_CAPACITY = 10;
/** 持有原始数据的List */ /**
* 持有原始数据的List
*/
private final List<Object> rawList; private final List<Object> rawList;
/** 配置项 */ /**
* 配置项
*/
private final JSONConfig config; private final JSONConfig config;
// -------------------------------------------------------------------------------------------------------------------- Constructor start // -------------------------------------------------------------------------------------------------------------------- Constructor start
/** /**
* 构造<br> * 构造<br>
* 默认使用{@link ArrayList} 实现 * 默认使用{@link ArrayList} 实现
@ -80,7 +87,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
* 默认使用{@link ArrayList} 实现 * 默认使用{@link ArrayList} 实现
* *
* @param initialCapacity 初始大小 * @param initialCapacity 初始大小
* @param config JSON配置项 * @param config JSON配置项
* @since 4.1.19 * @since 4.1.19
*/ */
public JSONArray(int initialCapacity, JSONConfig config) { public JSONArray(int initialCapacity, JSONConfig config) {
@ -161,7 +168,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
* 3. JSON数组字符串 * 3. JSON数组字符串
* </pre> * </pre>
* *
* @param object 数组或集合或JSON数组字符串 * @param object 数组或集合或JSON数组字符串
* @param ignoreNullValue 是否忽略空值 * @param ignoreNullValue 是否忽略空值
* @throws JSONException 非数组或集合 * @throws JSONException 非数组或集合
*/ */
@ -179,7 +186,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
* 3. JSON数组字符串 * 3. JSON数组字符串
* </pre> * </pre>
* *
* @param object 数组或集合或JSON数组字符串 * @param object 数组或集合或JSON数组字符串
* @param jsonConfig JSON选项 * @param jsonConfig JSON选项
* @throws JSONException 非数组或集合 * @throws JSONException 非数组或集合
* @since 4.6.5 * @since 4.6.5
@ -284,9 +291,10 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
* @param value 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL. * @param value 值对象. 可以是以下类型: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, or the JSONNull.NULL.
* @return this. * @return this.
* @throws JSONException index &lt; 0 或者非有限的数字 * @throws JSONException index &lt; 0 或者非有限的数字
* @see #set(int, Object)
*/ */
public JSONArray put(int index, Object value) throws JSONException { public JSONArray put(int index, Object value) throws JSONException {
this.add(index, value); this.set(index, value);
return this; return this;
} }
@ -335,7 +343,6 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
} }
} }
@SuppressWarnings("NullableProblems")
@Override @Override
public Iterator<Object> iterator() { public Iterator<Object> iterator() {
return rawList.iterator(); return rawList.iterator();
@ -441,6 +448,13 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, 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 @Override
public Object set(int index, Object element) { public Object set(int index, Object element) {
return this.rawList.set(index, JSONUtil.wrap(element, this.config)); return this.rawList.set(index, JSONUtil.wrap(element, this.config));
@ -473,19 +487,16 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
return this.rawList.lastIndexOf(o); return this.rawList.lastIndexOf(o);
} }
@SuppressWarnings("NullableProblems")
@Override @Override
public ListIterator<Object> listIterator() { public ListIterator<Object> listIterator() {
return this.rawList.listIterator(); return this.rawList.listIterator();
} }
@SuppressWarnings("NullableProblems")
@Override @Override
public ListIterator<Object> listIterator(int index) { public ListIterator<Object> listIterator(int index) {
return this.rawList.listIterator(index); return this.rawList.listIterator(index);
} }
@SuppressWarnings("NullableProblems")
@Override @Override
public List<Object> subList(int fromIndex, int toIndex) { public List<Object> subList(int fromIndex, int toIndex) {
return this.rawList.subList(fromIndex, toIndex); return this.rawList.subList(fromIndex, toIndex);
@ -504,7 +515,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
/** /**
* 转为{@link ArrayList} * 转为{@link ArrayList}
* *
* @param <T> 元素类型 * @param <T> 元素类型
* @param elementType 元素类型 * @param elementType 元素类型
* @return {@link ArrayList} * @return {@link ArrayList}
* @since 3.0.8 * @since 3.0.8
@ -537,9 +548,9 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
/** /**
* 将JSON内容写入Writer * 将JSON内容写入Writer
* *
* @param writer writer * @param writer writer
* @param indentFactor 缩进因子定义每一级别增加的缩进量 * @param indentFactor 缩进因子定义每一级别增加的缩进量
* @param indent 本级别缩进量 * @param indent 本级别缩进量
* @return Writer * @return Writer
* @throws IOException IO相关异常 * @throws IOException IO相关异常
*/ */
@ -579,7 +590,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
* @param source 数组或集合或JSON数组字符串 * @param source 数组或集合或JSON数组字符串
* @throws JSONException 非数组或集合 * @throws JSONException 非数组或集合
*/ */
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({"rawtypes", "unchecked"})
private void init(Object source) throws JSONException { private void init(Object source) throws JSONException {
if (null == source) { if (null == source) {
return; return;
@ -592,7 +603,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
} else if (source instanceof CharSequence) { } else if (source instanceof CharSequence) {
// JSON字符串 // JSON字符串
init((CharSequence) source); init((CharSequence) source);
}else if (source instanceof JSONTokener) { } else if (source instanceof JSONTokener) {
init((JSONTokener) source); init((JSONTokener) source);
} else { } else {
Iterator<?> iter; Iterator<?> iter;
@ -610,7 +621,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
while (iter.hasNext()) { while (iter.hasNext()) {
next = iter.next(); next = iter.next();
// 检查循环引用 // 检查循环引用
if(next != source){ if (next != source) {
this.add(next); this.add(next);
} }
} }
@ -639,7 +650,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
} }
if (x.nextClean() != ']') { if (x.nextClean() != ']') {
x.back(); x.back();
for (;;) { for (; ; ) {
if (x.nextClean() == ',') { if (x.nextClean() == ',') {
x.back(); x.back();
this.rawList.add(JSONNull.NULL); this.rawList.add(JSONNull.NULL);
@ -648,16 +659,16 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
this.rawList.add(x.nextValue()); this.rawList.add(x.nextValue());
} }
switch (x.nextClean()) { switch (x.nextClean()) {
case ',': case ',':
if (x.nextClean() == ']') { if (x.nextClean() == ']') {
return;
}
x.back();
break;
case ']':
return; return;
} default:
x.back(); throw x.syntaxError("Expected a ',' or ']'");
break;
case ']':
return;
default:
throw x.syntaxError("Expected a ',' or ']'");
} }
} }
} }

View File

@ -25,10 +25,10 @@ import java.math.BigInteger;
import java.util.Collection; import java.util.Collection;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.TreeMap;
import java.util.Map; import java.util.Map;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.Set; import java.util.Set;
import java.util.SortedMap;
/** /**
* JSON对象<br> * JSON对象<br>
@ -158,7 +158,7 @@ public class JSONObject implements JSON, JSONGetter<String>, Map<String, Object>
* @since 3.0.9 * @since 3.0.9
*/ */
public JSONObject(Object source, boolean ignoreNullValue) { public JSONObject(Object source, boolean ignoreNullValue) {
this(source, ignoreNullValue, (source instanceof LinkedHashMap) || (source instanceof TreeMap)); this(source, ignoreNullValue, (source instanceof LinkedHashMap) || (source instanceof SortedMap));
} }
/** /**