mirror of
https://gitee.com/dromara/hutool.git
synced 2025-05-04 12:47:59 +08:00
fix StrBuilder bug
This commit is contained in:
parent
60f3970b04
commit
4f811fc984
@ -13,6 +13,8 @@
|
||||
* 【extra】 修复Mail中sslEnable无效问题(pr#74@Gitee)
|
||||
* 【extra】 修复CsvParser中最后一行双引号没有去除的问题(pr#73@Gitee)
|
||||
* 【crypto】 修复SM2算法在自定义密钥时无效问题(issue#I12P5I@Gitee)
|
||||
* 【core】 修复StopWatch.prettyPrint条件问题(issue#I12RAC@Gitee)
|
||||
* 【core】 修复StrBuilder.del无法删除最后一个字符的问题(issue#I12R14@Gitee)
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -312,7 +312,7 @@ public class StopWatch {
|
||||
public String prettyPrint() {
|
||||
StringBuilder sb = new StringBuilder(shortSummary());
|
||||
sb.append(FileUtil.getLineSeparator());
|
||||
if (null != this.taskList) {
|
||||
if (null == this.taskList) {
|
||||
sb.append("No task info kept");
|
||||
} else {
|
||||
sb.append("---------------------------------------------").append(FileUtil.getLineSeparator());
|
||||
|
@ -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,16 +16,23 @@ 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() {
|
||||
@ -34,6 +41,7 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
||||
|
||||
/**
|
||||
* 创建字符串构建器
|
||||
*
|
||||
* @param initialCapacity 初始容量
|
||||
* @return {@link StrBuilder}
|
||||
*/
|
||||
@ -43,6 +51,7 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
||||
|
||||
/**
|
||||
* 创建字符串构建器
|
||||
*
|
||||
* @param strs 初始字符串
|
||||
* @return {@link StrBuilder}
|
||||
* @since 4.0.1
|
||||
@ -52,6 +61,7 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------ Constructor start
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*/
|
||||
@ -76,13 +86,14 @@ 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
|
||||
|
||||
/**
|
||||
* 追加对象,对象会被转换为字符串
|
||||
*
|
||||
@ -120,7 +131,7 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
||||
/**
|
||||
* 追加一个字符数组
|
||||
*
|
||||
* @param src 字符数组
|
||||
* @param src 字符数组
|
||||
* @param srcPos 开始位置(包括)
|
||||
* @param length 长度
|
||||
* @return this
|
||||
@ -140,6 +151,7 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------ Insert
|
||||
|
||||
/**
|
||||
* 追加对象,对象会被转换为字符串
|
||||
*
|
||||
@ -157,7 +169,7 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
||||
* 插入指定字符
|
||||
*
|
||||
* @param index 位置
|
||||
* @param c 字符
|
||||
* @param c 字符
|
||||
* @return this
|
||||
*/
|
||||
public StrBuilder insert(int index, char c) {
|
||||
@ -173,7 +185,7 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
||||
* 如果插入位置大于当前位置,则中间部分补充空格
|
||||
*
|
||||
* @param index 插入位置
|
||||
* @param src 源数组
|
||||
* @param src 源数组
|
||||
* @return this
|
||||
*/
|
||||
public StrBuilder insert(int index, char[] src) {
|
||||
@ -188,8 +200,8 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
||||
* 如果插入位置为当前位置,则定义为追加<br>
|
||||
* 如果插入位置大于当前位置,则中间部分补充空格
|
||||
*
|
||||
* @param index 插入位置
|
||||
* @param src 源数组
|
||||
* @param index 插入位置
|
||||
* @param src 源数组
|
||||
* @param srcPos 位置
|
||||
* @param length 长度
|
||||
* @return this
|
||||
@ -221,7 +233,7 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
||||
* 如果插入位置大于当前位置,则中间部分补充空格
|
||||
*
|
||||
* @param index 位置
|
||||
* @param csq 字符串
|
||||
* @param csq 字符串
|
||||
* @return this
|
||||
*/
|
||||
public StrBuilder insert(int index, CharSequence csq) {
|
||||
@ -253,9 +265,9 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
||||
* 如果插入位置大于当前位置,则中间部分补充空格
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
@ -360,38 +373,48 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
||||
*/
|
||||
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;
|
||||
}
|
||||
@ -462,7 +485,7 @@ 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) {
|
||||
@ -530,7 +554,7 @@ public class StrBuilder implements CharSequence, Appendable, Serializable {
|
||||
*/
|
||||
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;
|
||||
|
@ -86,4 +86,35 @@ public class StrBuilderTest {
|
||||
builder.append(123).append(456.123D).append(true).append('\n');
|
||||
Assert.assertEquals("123456.123true\n", builder.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void delTest() {
|
||||
// 删除全部测试
|
||||
StrBuilder strBuilder = new StrBuilder("ABCDEFG");
|
||||
int length = strBuilder.length();
|
||||
StrBuilder builder = strBuilder.del(0, length);
|
||||
Assert.assertEquals("", builder.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void delTest2() {
|
||||
// 删除中间部分测试
|
||||
StrBuilder strBuilder = new StrBuilder("ABCDEFG");
|
||||
int length = strBuilder.length();
|
||||
StrBuilder builder = strBuilder.del(2,6);
|
||||
Assert.assertEquals("ABG", builder.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void delToTest() {
|
||||
StrBuilder strBuilder = new StrBuilder("ABCDEFG");
|
||||
|
||||
// 不处理
|
||||
StrBuilder builder = strBuilder.delTo(7);
|
||||
Assert.assertEquals("ABCDEFG", builder.toString());
|
||||
|
||||
// 删除全部
|
||||
builder = strBuilder.delTo(0);
|
||||
Assert.assertEquals("", builder.toString());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user