|
|
@@ -1,12 +1,12 @@
|
|
|
package cn.hutool.core.text;
|
|
|
|
|
|
-import java.io.Serializable;
|
|
|
-import java.util.Arrays;
|
|
|
-
|
|
|
import cn.hutool.core.convert.Convert;
|
|
|
import cn.hutool.core.util.ArrayUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
|
|
|
+import java.io.Serializable;
|
|
|
+import java.util.Arrays;
|
|
|
+
|
|
|
/**
|
|
|
* 可复用的字符串生成器,非线程安全
|
|
|
*
|
|
|
@@ -16,33 +16,42 @@ import cn.hutool.core.util.StrUtil;
|
|
|
public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
private static final long serialVersionUID = 6341229705927508451L;
|
|
|
|
|
|
- /** 默认容量 */
|
|
|
+ /**
|
|
|
+ * 默认容量
|
|
|
+ */
|
|
|
public static final int DEFAULT_CAPACITY = 16;
|
|
|
|
|
|
- /** 存放的字符数组 */
|
|
|
+ /**
|
|
|
+ * 存放的字符数组
|
|
|
+ */
|
|
|
private char[] value;
|
|
|
- /** 当前指针位置,或者叫做已经加入的字符数,此位置总在最后一个字符之后 */
|
|
|
+ /**
|
|
|
+ * 当前指针位置,或者叫做已经加入的字符数,此位置总在最后一个字符之后
|
|
|
+ */
|
|
|
private int position;
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 创建字符串构建器
|
|
|
+ *
|
|
|
* @return {@link StrBuilder}
|
|
|
*/
|
|
|
public static StrBuilder create() {
|
|
|
return new StrBuilder();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 创建字符串构建器
|
|
|
+ *
|
|
|
* @param initialCapacity 初始容量
|
|
|
* @return {@link StrBuilder}
|
|
|
*/
|
|
|
public static StrBuilder create(int initialCapacity) {
|
|
|
return new StrBuilder(initialCapacity);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 创建字符串构建器
|
|
|
+ *
|
|
|
* @param strs 初始字符串
|
|
|
* @return {@link StrBuilder}
|
|
|
* @since 4.0.1
|
|
|
@@ -52,6 +61,7 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------ Constructor start
|
|
|
+
|
|
|
/**
|
|
|
* 构造
|
|
|
*/
|
|
|
@@ -67,7 +77,7 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
public StrBuilder(int initialCapacity) {
|
|
|
value = new char[initialCapacity];
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 构造
|
|
|
*
|
|
|
@@ -76,16 +86,17 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
*/
|
|
|
public StrBuilder(CharSequence... strs) {
|
|
|
this(ArrayUtil.isEmpty(strs) ? DEFAULT_CAPACITY : (totalLength(strs) + DEFAULT_CAPACITY));
|
|
|
- for(int i = 0; i < strs.length; i++) {
|
|
|
+ for (int i = 0; i < strs.length; i++) {
|
|
|
append(strs[i]);
|
|
|
}
|
|
|
}
|
|
|
// ------------------------------------------------------------------------------------ Constructor end
|
|
|
|
|
|
// ------------------------------------------------------------------------------------ Append
|
|
|
+
|
|
|
/**
|
|
|
* 追加对象,对象会被转换为字符串
|
|
|
- *
|
|
|
+ *
|
|
|
* @param obj 对象
|
|
|
* @return this
|
|
|
*/
|
|
|
@@ -106,7 +117,7 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
|
|
|
/**
|
|
|
* 追加一个字符数组
|
|
|
- *
|
|
|
+ *
|
|
|
* @param src 字符数组
|
|
|
* @return this
|
|
|
*/
|
|
|
@@ -119,8 +130,8 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
|
|
|
/**
|
|
|
* 追加一个字符数组
|
|
|
- *
|
|
|
- * @param src 字符数组
|
|
|
+ *
|
|
|
+ * @param src 字符数组
|
|
|
* @param srcPos 开始位置(包括)
|
|
|
* @param length 长度
|
|
|
* @return this
|
|
|
@@ -140,9 +151,10 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------ Insert
|
|
|
+
|
|
|
/**
|
|
|
* 追加对象,对象会被转换为字符串
|
|
|
- *
|
|
|
+ *
|
|
|
* @param obj 对象
|
|
|
* @return this
|
|
|
*/
|
|
|
@@ -155,9 +167,9 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
|
|
|
/**
|
|
|
* 插入指定字符
|
|
|
- *
|
|
|
+ *
|
|
|
* @param index 位置
|
|
|
- * @param c 字符
|
|
|
+ * @param c 字符
|
|
|
* @return this
|
|
|
*/
|
|
|
public StrBuilder insert(int index, char c) {
|
|
|
@@ -171,9 +183,9 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
* 指定位置插入数据<br>
|
|
|
* 如果插入位置为当前位置,则定义为追加<br>
|
|
|
* 如果插入位置大于当前位置,则中间部分补充空格
|
|
|
- *
|
|
|
+ *
|
|
|
* @param index 插入位置
|
|
|
- * @param src 源数组
|
|
|
+ * @param src 源数组
|
|
|
* @return this
|
|
|
*/
|
|
|
public StrBuilder insert(int index, char[] src) {
|
|
|
@@ -187,9 +199,9 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
* 指定位置插入数据<br>
|
|
|
* 如果插入位置为当前位置,则定义为追加<br>
|
|
|
* 如果插入位置大于当前位置,则中间部分补充空格
|
|
|
- *
|
|
|
- * @param index 插入位置
|
|
|
- * @param src 源数组
|
|
|
+ *
|
|
|
+ * @param index 插入位置
|
|
|
+ * @param src 源数组
|
|
|
* @param srcPos 位置
|
|
|
* @param length 长度
|
|
|
* @return this
|
|
|
@@ -219,9 +231,9 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
* 指定位置插入字符串的某个部分<br>
|
|
|
* 如果插入位置为当前位置,则定义为追加<br>
|
|
|
* 如果插入位置大于当前位置,则中间部分补充空格
|
|
|
- *
|
|
|
+ *
|
|
|
* @param index 位置
|
|
|
- * @param csq 字符串
|
|
|
+ * @param csq 字符串
|
|
|
* @return this
|
|
|
*/
|
|
|
public StrBuilder insert(int index, CharSequence csq) {
|
|
|
@@ -251,11 +263,11 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
* 指定位置插入字符串的某个部分<br>
|
|
|
* 如果插入位置为当前位置,则定义为追加<br>
|
|
|
* 如果插入位置大于当前位置,则中间部分补充空格
|
|
|
- *
|
|
|
+ *
|
|
|
* @param index 位置
|
|
|
- * @param csq 字符串
|
|
|
+ * @param csq 字符串
|
|
|
* @param start 字符串开始位置(包括)
|
|
|
- * @param end 字符串结束位置(不包括)
|
|
|
+ * @param end 字符串结束位置(不包括)
|
|
|
* @return this
|
|
|
*/
|
|
|
public StrBuilder insert(int index, CharSequence csq, int start, int end) {
|
|
|
@@ -289,12 +301,13 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------ Others
|
|
|
+
|
|
|
/**
|
|
|
* 将指定段的字符列表写出到目标字符数组中
|
|
|
- *
|
|
|
+ *
|
|
|
* @param srcBegin 起始位置(包括)
|
|
|
- * @param srcEnd 结束位置(不包括)
|
|
|
- * @param dst 目标数组
|
|
|
+ * @param srcEnd 结束位置(不包括)
|
|
|
+ * @param dst 目标数组
|
|
|
* @param dstBegin 目标起始位置(包括)
|
|
|
* @return this
|
|
|
*/
|
|
|
@@ -316,7 +329,7 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
|
|
|
/**
|
|
|
* 是否有内容
|
|
|
- *
|
|
|
+ *
|
|
|
* @return 是否有内容
|
|
|
*/
|
|
|
public boolean hasContent() {
|
|
|
@@ -325,16 +338,16 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
|
|
|
/**
|
|
|
* 是否为空
|
|
|
- *
|
|
|
+ *
|
|
|
* @return 是否为空
|
|
|
*/
|
|
|
public boolean isEmpty() {
|
|
|
return position == 0;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 删除全部字符,位置归零
|
|
|
- *
|
|
|
+ *
|
|
|
* @return this
|
|
|
*/
|
|
|
public StrBuilder clear() {
|
|
|
@@ -343,7 +356,7 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
|
|
|
/**
|
|
|
* 删除全部字符,位置归零
|
|
|
- *
|
|
|
+ *
|
|
|
* @return this
|
|
|
*/
|
|
|
public StrBuilder reset() {
|
|
|
@@ -354,51 +367,61 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
/**
|
|
|
* 删除到指定位置<br>
|
|
|
* 如果新位置小于等于0,则删除全部
|
|
|
- *
|
|
|
+ *
|
|
|
* @param newPosition 新的位置,不包括这个位置
|
|
|
* @return this
|
|
|
*/
|
|
|
public StrBuilder delTo(int newPosition) {
|
|
|
if (newPosition < 0) {
|
|
|
- this.reset();
|
|
|
- } else if (newPosition < this.position) {
|
|
|
- this.position = newPosition;
|
|
|
+ newPosition = 0;
|
|
|
}
|
|
|
- return this;
|
|
|
+ return del(newPosition, this.position);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 删除指定长度的字符
|
|
|
- *
|
|
|
- * @param start 开始位置(包括)
|
|
|
- * @param end 结束位置(不包括)
|
|
|
+ * 删除指定长度的字符,规则如下:
|
|
|
+ *
|
|
|
+ * <pre>
|
|
|
+ * 1、end大于等于最大长度,结束按照最大长度计算,相当于删除start之后虽有部分(性能最好)
|
|
|
+ * 2、end小于start时,抛出StringIndexOutOfBoundsException
|
|
|
+ * 3、start小于0 按照0处理
|
|
|
+ * 4、start等于end不处理
|
|
|
+ * 5、start和end都位于长度区间内,删除这段内容(内存拷贝)
|
|
|
+ * </pre>
|
|
|
+ *
|
|
|
+ * @param start 开始位置,负数按照0处理(包括)
|
|
|
+ * @param end 结束位置,超出最大长度按照最大长度处理(不包括)
|
|
|
* @return this
|
|
|
+ * @throws StringIndexOutOfBoundsException 当start > end抛出此异常
|
|
|
*/
|
|
|
- public StrBuilder del(int start, int end) {
|
|
|
+ public StrBuilder del(int start, int end) throws StringIndexOutOfBoundsException {
|
|
|
if (start < 0) {
|
|
|
start = 0;
|
|
|
}
|
|
|
- if (end > this.position) {
|
|
|
- end = this.position;
|
|
|
- }
|
|
|
- if (start > end) {
|
|
|
- throw new StringIndexOutOfBoundsException("Start is greater than End.");
|
|
|
- }
|
|
|
- if (end == this.position) {
|
|
|
+
|
|
|
+ if (end >= this.position) {
|
|
|
+ // end在边界及以外,相当于删除后半部分
|
|
|
this.position = start;
|
|
|
+ return this;
|
|
|
+ } else if (end < 0) {
|
|
|
+ // start和end都为0的情况下表示删除全部
|
|
|
+ end = 0;
|
|
|
}
|
|
|
|
|
|
int len = end - start;
|
|
|
+ // 截取中间部分,需要将后半部分复制到删除的开始位置
|
|
|
if (len > 0) {
|
|
|
System.arraycopy(value, start + len, value, start, this.position - end);
|
|
|
this.position -= len;
|
|
|
+ } else if (len < 0) {
|
|
|
+ throw new StringIndexOutOfBoundsException("Start is greater than End.");
|
|
|
}
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 生成字符串
|
|
|
- *
|
|
|
+ *
|
|
|
* @param isReset 是否重置,重置后相当于空的构建器
|
|
|
* @return 生成的字符串
|
|
|
*/
|
|
|
@@ -415,7 +438,7 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
|
|
|
/**
|
|
|
* 重置并返回生成的字符串
|
|
|
- *
|
|
|
+ *
|
|
|
* @return 字符串
|
|
|
*/
|
|
|
public String toStringAndReset() {
|
|
|
@@ -450,7 +473,7 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
|
|
|
/**
|
|
|
* 返回自定段的字符串
|
|
|
- *
|
|
|
+ *
|
|
|
* @param start 开始位置(包括)
|
|
|
* @return this
|
|
|
*/
|
|
|
@@ -460,9 +483,9 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
|
|
|
/**
|
|
|
* 返回自定段的字符串
|
|
|
- *
|
|
|
+ *
|
|
|
* @param start 开始位置(包括)
|
|
|
- * @param end 结束位置(不包括)
|
|
|
+ * @param end 结束位置(不包括)
|
|
|
* @return this
|
|
|
*/
|
|
|
public String subString(int start, int end) {
|
|
|
@@ -470,10 +493,11 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------ Private method start
|
|
|
+
|
|
|
/**
|
|
|
* 指定位置之后的数据后移指定长度
|
|
|
- *
|
|
|
- * @param index 位置
|
|
|
+ *
|
|
|
+ * @param index 位置
|
|
|
* @param length 位移长度
|
|
|
*/
|
|
|
private void moveDataAfterIndex(int index, int length) {
|
|
|
@@ -490,7 +514,7 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
|
|
|
/**
|
|
|
* 确认容量是否够用,不够用则扩展容量
|
|
|
- *
|
|
|
+ *
|
|
|
* @param minimumCapacity 最小容量
|
|
|
*/
|
|
|
private void ensureCapacity(int minimumCapacity) {
|
|
|
@@ -502,7 +526,7 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
/**
|
|
|
* 扩展容量<br>
|
|
|
* 首先对容量进行二倍扩展,如果小于最小容量,则扩展为最小容量
|
|
|
- *
|
|
|
+ *
|
|
|
* @param minimumCapacity 需要扩展的最小容量
|
|
|
*/
|
|
|
private void expandCapacity(int minimumCapacity) {
|
|
|
@@ -519,18 +543,18 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
|
|
}
|
|
|
value = Arrays.copyOf(value, newCapacity);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 给定字符串数组的总长度<br>
|
|
|
* null字符长度定义为0
|
|
|
- *
|
|
|
+ *
|
|
|
* @param strs 字符串数组
|
|
|
* @return 总长度
|
|
|
* @since 4.0.1
|
|
|
*/
|
|
|
private static int totalLength(CharSequence... strs) {
|
|
|
int totalLength = 0;
|
|
|
- for(int i = 0 ; i < strs.length; i++) {
|
|
|
+ for (int i = 0; i < strs.length; i++) {
|
|
|
totalLength += (null == strs[i] ? 4 : strs[i].length());
|
|
|
}
|
|
|
return totalLength;
|