mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
fix code to replace join
This commit is contained in:
parent
40a14e1508
commit
7baac80d32
@ -7,59 +7,81 @@ import java.util.NoSuchElementException;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 数组Iterator对象
|
* 数组Iterator对象
|
||||||
* @author Looly
|
|
||||||
*
|
*
|
||||||
* @param <E> 元素类型
|
* @param <E> 元素类型
|
||||||
|
* @author Looly
|
||||||
* @since 4.1.1
|
* @since 4.1.1
|
||||||
*/
|
*/
|
||||||
public class ArrayIter<E> implements Iterator<E>, Iterable<E>, Serializable{
|
public class ArrayIter<E> implements Iterator<E>, Iterable<E>, Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/** 数组 */
|
/**
|
||||||
|
* 数组
|
||||||
|
*/
|
||||||
private final Object array;
|
private final Object array;
|
||||||
/** 起始位置 */
|
/**
|
||||||
|
* 起始位置
|
||||||
|
*/
|
||||||
private int startIndex;
|
private int startIndex;
|
||||||
/** 结束位置 */
|
/**
|
||||||
|
* 结束位置
|
||||||
|
*/
|
||||||
private int endIndex;
|
private int endIndex;
|
||||||
/** 当前位置 */
|
/**
|
||||||
|
* 当前位置
|
||||||
|
*/
|
||||||
private int index;
|
private int index;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
|
*
|
||||||
* @param array 数组
|
* @param array 数组
|
||||||
* @throws IllegalArgumentException array对象不为数组抛出此异常
|
* @throws IllegalArgumentException array对象不为数组抛出此异常
|
||||||
* @throws NullPointerException array对象为null
|
* @throws NullPointerException array对象为null
|
||||||
*/
|
*/
|
||||||
public ArrayIter(final Object array) {
|
public ArrayIter(E[] array) {
|
||||||
|
this((Object) array);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造
|
||||||
|
*
|
||||||
|
* @param array 数组
|
||||||
|
* @throws IllegalArgumentException array对象不为数组抛出此异常
|
||||||
|
* @throws NullPointerException array对象为null
|
||||||
|
*/
|
||||||
|
public ArrayIter(Object array) {
|
||||||
this(array, 0);
|
this(array, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
* @param array 数组
|
*
|
||||||
|
* @param array 数组
|
||||||
* @param startIndex 起始位置,当起始位置小于0或者大于结束位置,置为0。
|
* @param startIndex 起始位置,当起始位置小于0或者大于结束位置,置为0。
|
||||||
* @throws IllegalArgumentException array对象不为数组抛出此异常
|
* @throws IllegalArgumentException array对象不为数组抛出此异常
|
||||||
* @throws NullPointerException array对象为null
|
* @throws NullPointerException array对象为null
|
||||||
*/
|
*/
|
||||||
public ArrayIter(final Object array, final int startIndex) {
|
public ArrayIter(Object array, int startIndex) {
|
||||||
this(array, startIndex, -1);
|
this(array, startIndex, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
* @param array 数组
|
*
|
||||||
|
* @param array 数组
|
||||||
* @param startIndex 起始位置,当起始位置小于0或者大于结束位置,置为0。
|
* @param startIndex 起始位置,当起始位置小于0或者大于结束位置,置为0。
|
||||||
* @param endIndex 结束位置,当结束位置小于0或者大于数组长度,置为数组长度。
|
* @param endIndex 结束位置,当结束位置小于0或者大于数组长度,置为数组长度。
|
||||||
* @throws IllegalArgumentException array对象不为数组抛出此异常
|
* @throws IllegalArgumentException array对象不为数组抛出此异常
|
||||||
* @throws NullPointerException array对象为null
|
* @throws NullPointerException array对象为null
|
||||||
*/
|
*/
|
||||||
public ArrayIter(final Object array, final int startIndex, final int endIndex) {
|
public ArrayIter(final Object array, final int startIndex, final int endIndex) {
|
||||||
this.endIndex = Array.getLength(array);
|
this.endIndex = Array.getLength(array);
|
||||||
if(endIndex > 0 && endIndex < this.endIndex){
|
if (endIndex > 0 && endIndex < this.endIndex) {
|
||||||
this.endIndex = endIndex;
|
this.endIndex = endIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(startIndex >=0 && startIndex < this.endIndex){
|
if (startIndex >= 0 && startIndex < this.endIndex) {
|
||||||
this.startIndex = startIndex;
|
this.startIndex = startIndex;
|
||||||
}
|
}
|
||||||
this.array = array;
|
this.array = array;
|
||||||
@ -77,11 +99,12 @@ public class ArrayIter<E> implements Iterator<E>, Iterable<E>, Serializable{
|
|||||||
if (hasNext() == false) {
|
if (hasNext() == false) {
|
||||||
throw new NoSuchElementException();
|
throw new NoSuchElementException();
|
||||||
}
|
}
|
||||||
return (E)Array.get(array, index++);
|
return (E) Array.get(array, index++);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 不允许操作数组元素
|
* 不允许操作数组元素
|
||||||
|
*
|
||||||
* @throws UnsupportedOperationException always
|
* @throws UnsupportedOperationException always
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@ -91,6 +114,7 @@ public class ArrayIter<E> implements Iterator<E>, Iterable<E>, Serializable{
|
|||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得原始数组对象
|
* 获得原始数组对象
|
||||||
*
|
*
|
||||||
|
@ -6,10 +6,8 @@ import cn.hutool.core.lang.Filter;
|
|||||||
import cn.hutool.core.lang.func.Func1;
|
import cn.hutool.core.lang.func.Func1;
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.text.StrJoiner;
|
import cn.hutool.core.text.StrJoiner;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.ReflectUtil;
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -246,7 +244,7 @@ public class IterUtil {
|
|||||||
* @return 连接后的字符串
|
* @return 连接后的字符串
|
||||||
*/
|
*/
|
||||||
public static <T> String join(Iterator<T> iterator, CharSequence conjunction) {
|
public static <T> String join(Iterator<T> iterator, CharSequence conjunction) {
|
||||||
return join(iterator, conjunction, null, null);
|
return StrJoiner.of(conjunction).append(iterator).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -262,17 +260,11 @@ public class IterUtil {
|
|||||||
* @since 4.0.10
|
* @since 4.0.10
|
||||||
*/
|
*/
|
||||||
public static <T> String join(Iterator<T> iterator, CharSequence conjunction, String prefix, String suffix) {
|
public static <T> String join(Iterator<T> iterator, CharSequence conjunction, String prefix, String suffix) {
|
||||||
return join(iterator, conjunction, (item) -> {
|
return StrJoiner.of(conjunction, prefix, suffix)
|
||||||
if (ArrayUtil.isArray(item)) {
|
// 每个元素都添加前后缀
|
||||||
return ArrayUtil.join(ArrayUtil.wrap(item), conjunction, prefix, suffix);
|
.setWrapElement(true)
|
||||||
} else if (item instanceof Iterable) {
|
.append(iterator)
|
||||||
return CollUtil.join((Iterable<?>) item, conjunction, prefix, suffix);
|
.toString();
|
||||||
} else if (item instanceof Iterator) {
|
|
||||||
return join((Iterator<?>) item, conjunction, prefix, suffix);
|
|
||||||
} else {
|
|
||||||
return StrUtil.wrap(String.valueOf(item), prefix, suffix);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -291,7 +283,7 @@ public class IterUtil {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new StrJoiner(conjunction).append(iterator, func).toString();
|
return StrJoiner.of(conjunction).append(iterator, func).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package cn.hutool.core.io.resource;
|
package cn.hutool.core.io.resource;
|
||||||
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.core.io.FileUtil;
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.util.ClassUtil;
|
import cn.hutool.core.util.ClassUtil;
|
||||||
@ -9,6 +7,8 @@ import cn.hutool.core.util.ObjectUtil;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.core.util.URLUtil;
|
import cn.hutool.core.util.URLUtil;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClassPath单一资源访问类<br>
|
* ClassPath单一资源访问类<br>
|
||||||
* 传入路径path必须为相对路径,如果传入绝对路径,Linux路径会去掉开头的“/”,而Windows路径会直接报错。<br>
|
* 传入路径path必须为相对路径,如果传入绝对路径,Linux路径会去掉开头的“/”,而Windows路径会直接报错。<br>
|
||||||
|
@ -22,11 +22,38 @@ public class StrJoiner implements Appendable {
|
|||||||
private CharSequence delimiter;
|
private CharSequence delimiter;
|
||||||
private CharSequence prefix;
|
private CharSequence prefix;
|
||||||
private CharSequence suffix;
|
private CharSequence suffix;
|
||||||
/**
|
// 前缀和后缀是否包装每个元素,true表示包装每个元素,false包装整个字符串
|
||||||
* appendable中是否包含内容
|
private boolean wrapElement;
|
||||||
*/
|
// null元素处理逻辑
|
||||||
|
private NullMode nullMode = NullMode.NULL_STRING;
|
||||||
|
// 当结果为空时默认返回的拼接结果
|
||||||
|
private String emptyResult = StrUtil.EMPTY;
|
||||||
|
|
||||||
|
// appendable中是否包含内容,用于判断增加内容时,是否首先加入分隔符
|
||||||
private boolean hasContent;
|
private boolean hasContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用指定分隔符创建{@link StrJoiner}
|
||||||
|
*
|
||||||
|
* @param delimiter 分隔符
|
||||||
|
* @return {@link StrJoiner}
|
||||||
|
*/
|
||||||
|
public static StrJoiner of(CharSequence delimiter) {
|
||||||
|
return new StrJoiner(delimiter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用指定分隔符创建{@link StrJoiner}
|
||||||
|
*
|
||||||
|
* @param delimiter 分隔符
|
||||||
|
* @param prefix 前缀
|
||||||
|
* @param suffix 后缀
|
||||||
|
* @return {@link StrJoiner}
|
||||||
|
*/
|
||||||
|
public static StrJoiner of(CharSequence delimiter, CharSequence prefix, CharSequence suffix) {
|
||||||
|
return new StrJoiner(delimiter, prefix, suffix);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
@ -49,9 +76,9 @@ public class StrJoiner implements Appendable {
|
|||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
* @param delimiter 分隔符,{@code null}表示无连接符,直接拼接
|
* @param delimiter 分隔符,{@code null}表示无连接符,直接拼接
|
||||||
* @param prefix 前缀
|
* @param prefix 前缀
|
||||||
* @param suffix 后缀
|
* @param suffix 后缀
|
||||||
*/
|
*/
|
||||||
public StrJoiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix) {
|
public StrJoiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix) {
|
||||||
this(null, delimiter, prefix, suffix);
|
this(null, delimiter, prefix, suffix);
|
||||||
@ -62,18 +89,14 @@ public class StrJoiner implements Appendable {
|
|||||||
*
|
*
|
||||||
* @param appendable 字符串追加器,拼接的字符串都将加入到此,{@code null}使用默认{@link StringBuilder}
|
* @param appendable 字符串追加器,拼接的字符串都将加入到此,{@code null}使用默认{@link StringBuilder}
|
||||||
* @param delimiter 分隔符,{@code null}表示无连接符,直接拼接
|
* @param delimiter 分隔符,{@code null}表示无连接符,直接拼接
|
||||||
* @param prefix 前缀
|
* @param prefix 前缀
|
||||||
* @param suffix 后缀
|
* @param suffix 后缀
|
||||||
*/
|
*/
|
||||||
public StrJoiner(Appendable appendable, CharSequence delimiter,
|
public StrJoiner(Appendable appendable, CharSequence delimiter,
|
||||||
CharSequence prefix, CharSequence suffix) {
|
CharSequence prefix, CharSequence suffix) {
|
||||||
if (null != appendable) {
|
if (null != appendable) {
|
||||||
this.appendable = appendable;
|
this.appendable = appendable;
|
||||||
final String initStr = appendable.toString();
|
checkHasContent(appendable);
|
||||||
if (StrUtil.isNotEmpty(initStr) && false == StrUtil.endWith(initStr, delimiter)) {
|
|
||||||
// 用户传入的Appendable中已经存在内容,且末尾不是分隔符
|
|
||||||
this.hasContent = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.delimiter = delimiter;
|
this.delimiter = delimiter;
|
||||||
@ -115,34 +138,98 @@ public class StrJoiner implements Appendable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 追加{@link Iterator}中的元素到拼接器中
|
* 设置前缀和后缀是否包装每个元素
|
||||||
*
|
*
|
||||||
* @param <T> 元素类型
|
* @param wrapElement true表示包装每个元素,false包装整个字符串
|
||||||
* @param iterable 元素列表
|
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
public <T> StrJoiner append(Iterable<T> iterable) {
|
public StrJoiner setWrapElement(boolean wrapElement) {
|
||||||
return append(IterUtil.getIter(iterable));
|
this.wrapElement = wrapElement;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置{@code null}元素处理逻辑
|
||||||
|
*
|
||||||
|
* @param nullMode 逻辑枚举,可选忽略、转换为""或转换为null字符串
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public StrJoiner setNullMode(NullMode nullMode) {
|
||||||
|
this.nullMode = nullMode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置当没有任何元素加入时,默认返回的字符串,默认""
|
||||||
|
*
|
||||||
|
* @param emptyResult 默认字符串
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public StrJoiner setEmptyResult(String emptyResult) {
|
||||||
|
this.emptyResult = emptyResult;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 追加对象到拼接器中
|
||||||
|
*
|
||||||
|
* @param <T> 元素类型
|
||||||
|
* @param obj 对象,支持数组、集合等
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public <T> StrJoiner append(Object obj) {
|
||||||
|
if (null == obj) {
|
||||||
|
append((CharSequence) null);
|
||||||
|
} else if (ArrayUtil.isArray(obj)) {
|
||||||
|
append(new ArrayIter<>(obj));
|
||||||
|
} else if (obj instanceof Iterator) {
|
||||||
|
append((Iterator<?>) obj);
|
||||||
|
} else if (obj instanceof Iterable) {
|
||||||
|
append(((Iterable<?>) obj).iterator());
|
||||||
|
} else {
|
||||||
|
append(String.valueOf(obj));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 追加数组中的元素到拼接器中
|
||||||
|
*
|
||||||
|
* @param <T> 元素类型
|
||||||
|
* @param array 元素数组
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public <T> StrJoiner append(T[] array) {
|
||||||
|
if(null == array){
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
return append(new ArrayIter<>(array));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 追加{@link Iterator}中的元素到拼接器中
|
* 追加{@link Iterator}中的元素到拼接器中
|
||||||
*
|
*
|
||||||
* @param <T> 元素类型
|
* @param <T> 元素类型
|
||||||
* @param iterator 元素列表
|
* @param iterator 元素列表
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
public <T> StrJoiner append(Iterator<T> iterator) {
|
public <T> StrJoiner append(Iterator<T> iterator) {
|
||||||
return append(iterator, (t)->{
|
if(null == iterator){
|
||||||
if(ArrayUtil.isArray(t)){
|
return this;
|
||||||
return new StrJoiner(this.delimiter).append((Iterator<?>) new ArrayIter<>(t)).toString();
|
}
|
||||||
} else if(t instanceof Iterator){
|
return append(iterator, (t) -> StrJoiner.of(this.delimiter).append(t).toString());
|
||||||
return new StrJoiner(this.delimiter).append((Iterator<?>)t).toString();
|
}
|
||||||
} else if(t instanceof Iterable){
|
|
||||||
return new StrJoiner(this.delimiter).append((Iterable<?>)t).toString();
|
/**
|
||||||
}
|
* 追加数组中的元素到拼接器中
|
||||||
return String.valueOf(t);
|
*
|
||||||
});
|
* @param <T> 元素类型
|
||||||
|
* @param array 元素数组
|
||||||
|
* @param toStrFunc 元素对象转换为字符串的函数
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public <T> StrJoiner append(T[] array, Function<T, ? extends CharSequence> toStrFunc) {
|
||||||
|
return append((Iterator<T>) new ArrayIter<>(array), toStrFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -176,8 +263,26 @@ public class StrJoiner implements Appendable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StrJoiner append(CharSequence csq) {
|
public StrJoiner append(CharSequence csq) {
|
||||||
|
if (null == csq) {
|
||||||
|
switch (this.nullMode) {
|
||||||
|
case IGNORE:
|
||||||
|
return this;
|
||||||
|
case TO_EMPTY:
|
||||||
|
csq = StrUtil.EMPTY;
|
||||||
|
break;
|
||||||
|
case NULL_STRING:
|
||||||
|
csq = StrUtil.NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
prepare().append(csq);
|
final Appendable appendable = prepare();
|
||||||
|
if (wrapElement && StrUtil.isNotEmpty(this.prefix)) {
|
||||||
|
appendable.append(prefix);
|
||||||
|
}
|
||||||
|
appendable.append(csq);
|
||||||
|
if (wrapElement && StrUtil.isNotEmpty(this.suffix)) {
|
||||||
|
appendable.append(suffix);
|
||||||
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IORuntimeException(e);
|
throw new IORuntimeException(e);
|
||||||
}
|
}
|
||||||
@ -185,35 +290,46 @@ public class StrJoiner implements Appendable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StrJoiner append(CharSequence csq, int start, int end) {
|
public StrJoiner append(CharSequence csq, int startInclude, int endExclude) {
|
||||||
try {
|
return append(StrUtil.sub(csq, startInclude, endExclude));
|
||||||
prepare().append(csq, start, end);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new IORuntimeException(e);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StrJoiner append(char c) {
|
public StrJoiner append(char c) {
|
||||||
try {
|
return append(String.valueOf(c));
|
||||||
prepare().append(c);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new IORuntimeException(e);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (StrUtil.isNotEmpty(this.suffix)) {
|
if(null == this.appendable){
|
||||||
|
return emptyResult;
|
||||||
|
}
|
||||||
|
if (false == wrapElement && StrUtil.isNotEmpty(this.suffix)) {
|
||||||
try {
|
try {
|
||||||
appendable.append(this.suffix);
|
this.appendable.append(this.suffix);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IORuntimeException(e);
|
throw new IORuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return appendable.toString();
|
return this.appendable.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code null}处理的模式
|
||||||
|
*/
|
||||||
|
public enum NullMode {
|
||||||
|
/**
|
||||||
|
* 忽略{@code null},即null元素不加入拼接的字符串
|
||||||
|
*/
|
||||||
|
IGNORE,
|
||||||
|
/**
|
||||||
|
* {@code null}转为""
|
||||||
|
*/
|
||||||
|
TO_EMPTY,
|
||||||
|
/**
|
||||||
|
* {@code null}转为null字符串
|
||||||
|
*/
|
||||||
|
NULL_STRING
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -226,12 +342,33 @@ public class StrJoiner implements Appendable {
|
|||||||
if (hasContent) {
|
if (hasContent) {
|
||||||
this.appendable.append(delimiter);
|
this.appendable.append(delimiter);
|
||||||
} else {
|
} else {
|
||||||
this.appendable = new StringBuilder();
|
if (null == this.appendable) {
|
||||||
if (StrUtil.isNotEmpty(this.prefix)) {
|
this.appendable = new StringBuilder();
|
||||||
|
}
|
||||||
|
if (false == wrapElement && StrUtil.isNotEmpty(this.prefix)) {
|
||||||
this.appendable.append(this.prefix);
|
this.appendable.append(this.prefix);
|
||||||
}
|
}
|
||||||
this.hasContent = true;
|
this.hasContent = true;
|
||||||
}
|
}
|
||||||
return this.appendable;
|
return this.appendable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查用户传入的{@link Appendable} 是否已经存在内容,而且不能以分隔符结尾
|
||||||
|
*
|
||||||
|
* @param appendable {@link Appendable}
|
||||||
|
*/
|
||||||
|
private void checkHasContent(Appendable appendable) {
|
||||||
|
if (appendable instanceof CharSequence) {
|
||||||
|
final CharSequence charSequence = (CharSequence) appendable;
|
||||||
|
if (charSequence.length() > 0 && StrUtil.endWith(charSequence, delimiter)) {
|
||||||
|
this.hasContent = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final String initStr = appendable.toString();
|
||||||
|
if (StrUtil.isNotEmpty(initStr) && false == StrUtil.endWith(initStr, delimiter)) {
|
||||||
|
this.hasContent = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package cn.hutool.core.util;
|
|||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
import cn.hutool.core.collection.IterUtil;
|
|
||||||
import cn.hutool.core.comparator.CompareUtil;
|
import cn.hutool.core.comparator.CompareUtil;
|
||||||
import cn.hutool.core.exceptions.UtilException;
|
import cn.hutool.core.exceptions.UtilException;
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
@ -10,6 +9,7 @@ import cn.hutool.core.lang.Editor;
|
|||||||
import cn.hutool.core.lang.Filter;
|
import cn.hutool.core.lang.Filter;
|
||||||
import cn.hutool.core.lang.Matcher;
|
import cn.hutool.core.lang.Matcher;
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import cn.hutool.core.text.StrJoiner;
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@ -165,7 +165,7 @@ public class ArrayUtil extends PrimitiveArrayUtil {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> T firstMatch(Matcher<T> matcher, T... array) {
|
public static <T> T firstMatch(Matcher<T> matcher, T... array) {
|
||||||
final int index = matchIndex(matcher, array);
|
final int index = matchIndex(matcher, array);
|
||||||
if(index < 0){
|
if (index < 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,8 +184,8 @@ public class ArrayUtil extends PrimitiveArrayUtil {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> int matchIndex(Matcher<T> matcher, T... array) {
|
public static <T> int matchIndex(Matcher<T> matcher, T... array) {
|
||||||
if (isNotEmpty(array)) {
|
if (isNotEmpty(array)) {
|
||||||
for(int i = 0; i < array.length; i++){
|
for (int i = 0; i < array.length; i++) {
|
||||||
if(matcher.match(array[i])){
|
if (matcher.match(array[i])) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -621,7 +621,7 @@ public class ArrayUtil extends PrimitiveArrayUtil {
|
|||||||
* @since 3.2.1
|
* @since 3.2.1
|
||||||
*/
|
*/
|
||||||
public static <T> T[] filter(T[] array, Filter<T> filter) {
|
public static <T> T[] filter(T[] array, Filter<T> filter) {
|
||||||
if(null == array || null == filter){
|
if (null == array || null == filter) {
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
return edit(array, t -> filter.accept(t) ? t : null);
|
return edit(array, t -> filter.accept(t) ? t : null);
|
||||||
@ -737,7 +737,7 @@ public class ArrayUtil extends PrimitiveArrayUtil {
|
|||||||
* @since 3.0.7
|
* @since 3.0.7
|
||||||
*/
|
*/
|
||||||
public static <T> int indexOf(T[] array, Object value) {
|
public static <T> int indexOf(T[] array, Object value) {
|
||||||
return matchIndex((obj)-> ObjectUtil.equal(value, obj), array);
|
return matchIndex((obj) -> ObjectUtil.equal(value, obj), array);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1114,38 +1114,24 @@ public class ArrayUtil extends PrimitiveArrayUtil {
|
|||||||
/**
|
/**
|
||||||
* 以 conjunction 为分隔符将数组转换为字符串
|
* 以 conjunction 为分隔符将数组转换为字符串
|
||||||
*
|
*
|
||||||
* @param <T> 被处理的集合
|
* @param <T> 被处理的集合
|
||||||
* @param array 数组
|
* @param array 数组
|
||||||
* @param conjunction 分隔符
|
* @param delimiter 分隔符
|
||||||
* @param prefix 每个元素添加的前缀,null表示不添加
|
* @param prefix 每个元素添加的前缀,null表示不添加
|
||||||
* @param suffix 每个元素添加的后缀,null表示不添加
|
* @param suffix 每个元素添加的后缀,null表示不添加
|
||||||
* @return 连接后的字符串
|
* @return 连接后的字符串
|
||||||
* @since 4.0.10
|
* @since 4.0.10
|
||||||
*/
|
*/
|
||||||
public static <T> String join(T[] array, CharSequence conjunction, String prefix, String suffix) {
|
public static <T> String join(T[] array, CharSequence delimiter, String prefix, String suffix) {
|
||||||
if (null == array) {
|
if (null == array) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
return StrJoiner.of(delimiter, prefix, suffix)
|
||||||
boolean isFirst = true;
|
// 每个元素都添加前后缀
|
||||||
for (T item : array) {
|
.setWrapElement(true)
|
||||||
if (isFirst) {
|
.append(array)
|
||||||
isFirst = false;
|
.toString();
|
||||||
} else {
|
|
||||||
sb.append(conjunction);
|
|
||||||
}
|
|
||||||
if (ArrayUtil.isArray(item)) {
|
|
||||||
sb.append(join(ArrayUtil.wrap(item), conjunction, prefix, suffix));
|
|
||||||
} else if (item instanceof Iterable<?>) {
|
|
||||||
sb.append(CollUtil.join((Iterable<?>) item, conjunction, prefix, suffix));
|
|
||||||
} else if (item instanceof Iterator<?>) {
|
|
||||||
sb.append(IterUtil.join((Iterator<?>) item, conjunction, prefix, suffix));
|
|
||||||
} else {
|
|
||||||
sb.append(StrUtil.wrap(StrUtil.toString(item), prefix, suffix));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1159,26 +1145,7 @@ public class ArrayUtil extends PrimitiveArrayUtil {
|
|||||||
* @since 5.3.3
|
* @since 5.3.3
|
||||||
*/
|
*/
|
||||||
public static <T> String join(T[] array, CharSequence conjunction, Editor<T> editor) {
|
public static <T> String join(T[] array, CharSequence conjunction, Editor<T> editor) {
|
||||||
if (null == array) {
|
return StrJoiner.of(conjunction).append(array, (t)-> String.valueOf(editor.edit(t))).toString();
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
|
||||||
boolean isFirst = true;
|
|
||||||
for (T item : array) {
|
|
||||||
if (isFirst) {
|
|
||||||
isFirst = false;
|
|
||||||
} else {
|
|
||||||
sb.append(conjunction);
|
|
||||||
}
|
|
||||||
if (null != editor) {
|
|
||||||
item = editor.edit(item);
|
|
||||||
}
|
|
||||||
if (null != item) {
|
|
||||||
sb.append(StrUtil.toString(item));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1189,39 +1156,14 @@ public class ArrayUtil extends PrimitiveArrayUtil {
|
|||||||
* @return 连接后的字符串
|
* @return 连接后的字符串
|
||||||
*/
|
*/
|
||||||
public static String join(Object array, CharSequence conjunction) {
|
public static String join(Object array, CharSequence conjunction) {
|
||||||
if(null == array){
|
if (null == array) {
|
||||||
throw new NullPointerException("Array must be not null!");
|
return null;
|
||||||
}
|
}
|
||||||
if (false == isArray(array)) {
|
if (false == isArray(array)) {
|
||||||
throw new IllegalArgumentException(StrUtil.format("[{}] is not a Array!", array.getClass()));
|
throw new IllegalArgumentException(StrUtil.format("[{}] is not a Array!", array.getClass()));
|
||||||
}
|
}
|
||||||
|
|
||||||
final Class<?> componentType = array.getClass().getComponentType();
|
return StrJoiner.of(conjunction).append(array).toString();
|
||||||
if (componentType.isPrimitive()) {
|
|
||||||
final String componentTypeName = componentType.getName();
|
|
||||||
switch (componentTypeName) {
|
|
||||||
case "long":
|
|
||||||
return join((long[]) array, conjunction);
|
|
||||||
case "int":
|
|
||||||
return join((int[]) array, conjunction);
|
|
||||||
case "short":
|
|
||||||
return join((short[]) array, conjunction);
|
|
||||||
case "char":
|
|
||||||
return join((char[]) array, conjunction);
|
|
||||||
case "byte":
|
|
||||||
return join((byte[]) array, conjunction);
|
|
||||||
case "boolean":
|
|
||||||
return join((boolean[]) array, conjunction);
|
|
||||||
case "float":
|
|
||||||
return join((float[]) array, conjunction);
|
|
||||||
case "double":
|
|
||||||
return join((double[]) array, conjunction);
|
|
||||||
default:
|
|
||||||
throw new UtilException("Unknown primitive type: [{}]", componentTypeName);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return join((Object[]) array, conjunction);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1593,8 +1593,9 @@ public class PrimitiveArrayUtil {
|
|||||||
*
|
*
|
||||||
* @param array 数组
|
* @param array 数组
|
||||||
* @param conjunction 分隔符
|
* @param conjunction 分隔符
|
||||||
* @return 连接后的字符串
|
* @deprecated 请使用 {@link ArrayUtil#join(Object, CharSequence)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static String join(int[] array, CharSequence conjunction) {
|
public static String join(int[] array, CharSequence conjunction) {
|
||||||
if (null == array) {
|
if (null == array) {
|
||||||
return null;
|
return null;
|
||||||
@ -1618,8 +1619,9 @@ public class PrimitiveArrayUtil {
|
|||||||
*
|
*
|
||||||
* @param array 数组
|
* @param array 数组
|
||||||
* @param conjunction 分隔符
|
* @param conjunction 分隔符
|
||||||
* @return 连接后的字符串
|
* @deprecated 请使用 {@link ArrayUtil#join(Object, CharSequence)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static String join(long[] array, CharSequence conjunction) {
|
public static String join(long[] array, CharSequence conjunction) {
|
||||||
if (null == array) {
|
if (null == array) {
|
||||||
return null;
|
return null;
|
||||||
@ -1643,8 +1645,9 @@ public class PrimitiveArrayUtil {
|
|||||||
*
|
*
|
||||||
* @param array 数组
|
* @param array 数组
|
||||||
* @param conjunction 分隔符
|
* @param conjunction 分隔符
|
||||||
* @return 连接后的字符串
|
* @deprecated 请使用 {@link ArrayUtil#join(Object, CharSequence)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static String join(short[] array, CharSequence conjunction) {
|
public static String join(short[] array, CharSequence conjunction) {
|
||||||
if (null == array) {
|
if (null == array) {
|
||||||
return null;
|
return null;
|
||||||
@ -1668,8 +1671,9 @@ public class PrimitiveArrayUtil {
|
|||||||
*
|
*
|
||||||
* @param array 数组
|
* @param array 数组
|
||||||
* @param conjunction 分隔符
|
* @param conjunction 分隔符
|
||||||
* @return 连接后的字符串
|
* @deprecated 请使用 {@link ArrayUtil#join(Object, CharSequence)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static String join(char[] array, CharSequence conjunction) {
|
public static String join(char[] array, CharSequence conjunction) {
|
||||||
if (null == array) {
|
if (null == array) {
|
||||||
return null;
|
return null;
|
||||||
@ -1693,8 +1697,9 @@ public class PrimitiveArrayUtil {
|
|||||||
*
|
*
|
||||||
* @param array 数组
|
* @param array 数组
|
||||||
* @param conjunction 分隔符
|
* @param conjunction 分隔符
|
||||||
* @return 连接后的字符串
|
* @deprecated 请使用 {@link ArrayUtil#join(Object, CharSequence)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static String join(byte[] array, CharSequence conjunction) {
|
public static String join(byte[] array, CharSequence conjunction) {
|
||||||
if (null == array) {
|
if (null == array) {
|
||||||
return null;
|
return null;
|
||||||
@ -1719,7 +1724,9 @@ public class PrimitiveArrayUtil {
|
|||||||
* @param array 数组
|
* @param array 数组
|
||||||
* @param conjunction 分隔符
|
* @param conjunction 分隔符
|
||||||
* @return 连接后的字符串
|
* @return 连接后的字符串
|
||||||
|
* @deprecated 请使用 {@link ArrayUtil#join(Object, CharSequence)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static String join(boolean[] array, CharSequence conjunction) {
|
public static String join(boolean[] array, CharSequence conjunction) {
|
||||||
if (null == array) {
|
if (null == array) {
|
||||||
return null;
|
return null;
|
||||||
@ -1744,7 +1751,9 @@ public class PrimitiveArrayUtil {
|
|||||||
* @param array 数组
|
* @param array 数组
|
||||||
* @param conjunction 分隔符
|
* @param conjunction 分隔符
|
||||||
* @return 连接后的字符串
|
* @return 连接后的字符串
|
||||||
|
* @deprecated 请使用 {@link ArrayUtil#join(Object, CharSequence)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static String join(float[] array, CharSequence conjunction) {
|
public static String join(float[] array, CharSequence conjunction) {
|
||||||
if (null == array) {
|
if (null == array) {
|
||||||
return null;
|
return null;
|
||||||
@ -1769,7 +1778,9 @@ public class PrimitiveArrayUtil {
|
|||||||
* @param array 数组
|
* @param array 数组
|
||||||
* @param conjunction 分隔符
|
* @param conjunction 分隔符
|
||||||
* @return 连接后的字符串
|
* @return 连接后的字符串
|
||||||
|
* @deprecated 请使用 {@link ArrayUtil#join(Object, CharSequence)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static String join(double[] array, CharSequence conjunction) {
|
public static String join(double[] array, CharSequence conjunction) {
|
||||||
if (null == array) {
|
if (null == array) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -32,6 +32,7 @@ public class IterUtilTest {
|
|||||||
String join1 = IterUtil.join(list1.iterator(), ":");
|
String join1 = IterUtil.join(list1.iterator(), ":");
|
||||||
Assert.assertEquals("1:2:3:4", join1);
|
Assert.assertEquals("1:2:3:4", join1);
|
||||||
|
|
||||||
|
// 包装每个节点
|
||||||
ArrayList<String> list2 = CollUtil.newArrayList("1", "2", "3", "4");
|
ArrayList<String> list2 = CollUtil.newArrayList("1", "2", "3", "4");
|
||||||
String join2 = IterUtil.join(list2.iterator(), ":", "\"", "\"");
|
String join2 = IterUtil.join(list2.iterator(), ":", "\"", "\"");
|
||||||
Assert.assertEquals("\"1\":\"2\":\"3\":\"4\"", join2);
|
Assert.assertEquals("\"1\":\"2\":\"3\":\"4\"", join2);
|
||||||
@ -44,6 +45,13 @@ public class IterUtilTest {
|
|||||||
Assert.assertEquals("1:2:3:4", join);
|
Assert.assertEquals("1:2:3:4", join);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void joinWithNullTest() {
|
||||||
|
ArrayList<String> list = CollUtil.newArrayList("1", null, "3", "4");
|
||||||
|
String join = IterUtil.join(list.iterator(), ":", String::valueOf);
|
||||||
|
Assert.assertEquals("1:null:3:4", join);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testToListMap() {
|
public void testToListMap() {
|
||||||
Map<String, List<String>> expectedMap = new HashMap<>();
|
Map<String, List<String>> expectedMap = new HashMap<>();
|
||||||
|
@ -1,37 +1,37 @@
|
|||||||
package cn.hutool.core.io;
|
package cn.hutool.core.io;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.resource.ClassPathResource;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import cn.hutool.core.io.resource.ClassPathResource;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClassPath资源读取测试
|
* ClassPath资源读取测试
|
||||||
* @author Looly
|
|
||||||
*
|
*
|
||||||
|
* @author Looly
|
||||||
*/
|
*/
|
||||||
public class ClassPathResourceTest {
|
public class ClassPathResourceTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void readStringTest() throws IOException{
|
public void readStringTest() {
|
||||||
ClassPathResource resource = new ClassPathResource("test.properties");
|
ClassPathResource resource = new ClassPathResource("test.properties");
|
||||||
String content = resource.readUtf8Str();
|
String content = resource.readUtf8Str();
|
||||||
Assert.assertTrue(StrUtil.isNotEmpty(content));
|
Assert.assertTrue(StrUtil.isNotEmpty(content));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void readStringTest2() throws IOException{
|
public void readStringTest2() {
|
||||||
|
// 读取classpath根目录测试
|
||||||
ClassPathResource resource = new ClassPathResource("/");
|
ClassPathResource resource = new ClassPathResource("/");
|
||||||
String content = resource.readUtf8Str();
|
String content = resource.readUtf8Str();
|
||||||
Assert.assertTrue(StrUtil.isNotEmpty(content));
|
Assert.assertTrue(StrUtil.isNotEmpty(content));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void readTest() throws IOException{
|
public void readTest() throws IOException {
|
||||||
ClassPathResource resource = new ClassPathResource("test.properties");
|
ClassPathResource resource = new ClassPathResource("test.properties");
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
properties.load(resource.getStream());
|
properties.load(resource.getStream());
|
||||||
@ -41,7 +41,7 @@ public class ClassPathResourceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void readFromJarTest() throws IOException{
|
public void readFromJarTest() {
|
||||||
//测试读取junit的jar包下的LICENSE-junit.txt文件
|
//测试读取junit的jar包下的LICENSE-junit.txt文件
|
||||||
final ClassPathResource resource = new ClassPathResource("LICENSE-junit.txt");
|
final ClassPathResource resource = new ClassPathResource("LICENSE-junit.txt");
|
||||||
|
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
package cn.hutool.core.text;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class StrJoinerTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void joinIntArrayTest(){
|
||||||
|
int[] a = {1,2,3,4,5};
|
||||||
|
final StrJoiner append = StrJoiner.of(",").append(a);
|
||||||
|
Assert.assertEquals("1,2,3,4,5", append.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void joinEmptyTest(){
|
||||||
|
List<String> list = new ArrayList<>();
|
||||||
|
final StrJoiner append = StrJoiner.of(",").append(list);
|
||||||
|
Assert.assertEquals("", append.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void noJoinTest(){
|
||||||
|
final StrJoiner append = StrJoiner.of(",");
|
||||||
|
Assert.assertEquals("", append.toString());
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user