您的位置:首页 > 健康 > 美食 > 国外图片设计网站有哪些_电子产品外贸交易平台_深圳网络公司推广公司_运营推广公司

国外图片设计网站有哪些_电子产品外贸交易平台_深圳网络公司推广公司_运营推广公司

2025/4/10 15:09:34 来源:https://blog.csdn.net/qq_46030794/article/details/146444147  浏览:    关键词:国外图片设计网站有哪些_电子产品外贸交易平台_深圳网络公司推广公司_运营推广公司
国外图片设计网站有哪些_电子产品外贸交易平台_深圳网络公司推广公司_运营推广公司

1. 介绍

在这里插入图片描述
String中还有两个常用的类,StringBuffer和StringBuilder。这两个类都是专门为频繁进行拼接字符串而准备的。最先出现的是StringBuffer,之后到jdk1.5的时候才有了StringBuilder。

2. StringBuilder解析

在这里插入图片描述
从这张继承结构图可以看出:

  • StringBuilder继承了AbstractStringBuilder
  • StringBuilder实现了Comparable接口,这说明他是可比较的
  • StringBuilder实现了CharSequence接口,这说明他是一个可变的字符序列
  • StringBuilder实现了Appendable接口,这说明他具有可追加字符序列的能力
  • StringBuilder实现了Serializable接口,这说明他可以被序列化

在这里插入图片描述
在这里插入图片描述

StringBuilder继承了AbstractStringBuilder,而AbstractStringBuilder的底层是一个byte数组,并且前面没有加final进行修饰,因此他是可变的,可以进行扩容,而String类就是因为这个byte数组加了final关键字进行修饰,因此String是不可变的。那么既然StringBuilder可以进行扩容,在具体进行扩容操作又是如何实现的呢?接下来就要继续从源码进行查看。
StringBuilder有一个无参构造方法,默认初始化的容量是16.
在这里插入图片描述

2.1 第一个例子

接下来我们写一个具体的程序来看一下,在扩容的时候是如何进行操作的。

public class test {public static void main(String[] args) {StringBuilder sb = new StringBuilder();sb.append("Hello World");sb.append("123456");sb.append("3.1415926");System.out.println(sb);}
}

然后开始debug进行查看。首先是进入到Stringbuilder的这个append()方法
在这里插入图片描述
然后下一步会进入父类的append()方法。
在这里插入图片描述
这个方法就是确保他的容量,这里有一个count参数,代表最小容量,这个参数是指当前这个对象里面真实存储的元素的个数,现在是0,意味着这个对象创建出来之后,里面暂时还没有传入任何值。
在这里插入图片描述
进入到这个方法之后,这里有一个oldCapacity变量,因为初始化容量是16,因此这里这个值也是16,然后下一步判断这个最小容量minimumCapacity减去这个老容量oldCapacity是否大于0,此时可以看到值大于0为false,因此不会进去if中的扩容操作。
在这里插入图片描述
然后再看下一次的append()操作
在这里插入图片描述
同样的走到这一步,这个时候可以看见,最小容量minimumCapacity减去这个老容量oldCapacity大于0了,说明这里会进行扩容的操作,就会进入到newCapacity()这个方法。
在这里插入图片描述
到这一步可以看到此时的oldLength就是初始化的长度为16,newLength是预期的长度,也就是这个字符串拼接进去之后的长度,为17,增长就为17 - 16 = 1,接下来就要进入到ArraysSupport.newLength()这个方法中查看新长度为多少。
在这里插入图片描述
进入到方法之后,然后这里使用oldLength,也就是16,去加上Math.max(minGrowth, prefGrowth),在最小增长和预期增长之间的最大值,这里minGrowth为1,prefGrowth为18,因此最大值就是18,然后就是16 + 18 = 34。
在这里插入图片描述
然后回到newCapacity()方法,也可以看到length为34.
在这里插入图片描述
继续往下走,发现此时value值为34
在这里插入图片描述
当我们不指定初始容量时,会给一个默认的初始容量为16,从上面可以看到进行第一次扩容之后,新的容量为34.

2.2 第二个例子

我们在写一个程序进行测试,这次拼接的字符串稍微大一点

public class test {public static void main(String[] args) {StringBuilder sb = new StringBuilder();sb.append("3.1415926535897932384626433832795028841971");System.out.println(sb);}
}

还是一样先进入append()方法
在这里插入图片描述
再进入父类的append()方法,可以看到现在长度为42
在这里插入图片描述
然后进入到ensureCapacityInternal()方法,这次可以看到最小容量为42,旧容量为16,42 - 16 > 0,因此要进行扩容。
在这里插入图片描述
接着进入到newCapacity()方法,这个时候的增长growth就是42 - 16 = 26了,然后下一步进入ArraysSupport.newLength()方法
在这里插入图片描述
进去之后oldLength不变,还是16,但是这次的Math.max(minGrowth, prefGrowth),minGrowth为26,prefGrowth为18,那么最大值就是26,所以prefLength的值为42。后续步骤就和之前一样了。
在这里插入图片描述当我们不指定长度,并且添加的字符串长度过长时,扩容的时候,就直接使用当前这个字符串的长度。
如果这个时候,再添加一个字符串,比如sb.append(“helloworld123”);这个时候又会是什么样的呢?可以看到这个时候oldLength就是我们第一次拼接的长度为42,新长度为55,增长长度为 55 - 42 = 13,继续往下走
在这里插入图片描述
这个时候可以看到oldLength为42,Math.max(minGrowth, prefGrowth)方法取的最大值,最大值现在为44,因此扩容后的长度就是42 + 44 = 86.
在这里插入图片描述
那么扩容的测试到这里就结束了。我们可以看到,第一次初始化容量为16时,扩容容量为34,为16 * 2 + 2,这次再进行二次拼接时一开始为42,扩容容量为86,为42 * 2 + 2 ,可以明显看出每次扩容是原来容量的2倍再加2.原因就是因为这段代码,从上面调试来看,扩容时都是oldLength + (oldLength + 2),即oldLength * 2 + 2.
在这里插入图片描述

3. 扩容总结

  1. StringBuilder的扩容策略是从当前容量开始,每次扩容为原来的2倍再加2
  2. 如果一开始拼接的字符串的长度就超过了默认初始容量16时,那么StringBuilder扩容的容量就直接为一开始的字符串长度
  3. 如果我们想要进行优化,那么就要在创建StringBuilder时,预估一下我们要拼接的字符串的长度,然后给定一个合适的初始化容量,从而减少底层的扩容操作。

4. 构造方法和常用方法

4.1 构造方法

方法描述
StringBuilder()构造一个字符串生成器,其中不包含任何字符,初始容量为16个字符
StringBuilder(int capacity)构造一个字符串生成器,其中不包含任何字符,并且具有由容量参数指定的初始容量
StringBuilder(String str)构造初始化为指定字符串内容的字符串生成器

用法如下:
在这里插入图片描述

4.2 常用方法

  1. append(),追加方法,这个里面可以传多种不同类型的值
    在这里插入图片描述

  2. delete():删除方法
    在这里插入图片描述

public class test {public static void main(String[] args) {StringBuilder sb1 = new StringBuilder("abcdefg");/*** delete(int start, int end)* 删除从指定位置开始,到指定位置结束的字符* 左闭右开:[start, end]*/sb1.delete(0,3);System.out.println(sb1); //defg/*** deleteCharAt(int index)* 删除指定位置的字符*/StringBuilder sb2 = new StringBuilder("abcdefg");sb2.deleteCharAt(5); // abcdegSystem.out.println(sb2);}
}
  1. insert():插入方法,在指定位置添加的方法,可以添加多种类型的值
    在这里插入图片描述
public class test {public static void main(String[] args) {StringBuilder sb1 = new StringBuilder("abcdefg");/*** insert(int offset, String str)* 在指定位置上添加一个字符串*/sb1.insert(3, "HELLO"); // abcHELLOdefgSystem.out.println(sb1);}
}
  1. replace(int start, int end, String str):替换方法
public class test {public static void main(String[] args) {StringBuilder sb1 = new StringBuilder("abcdefg");/*** replace(int start, int end, String str)* 从指定位置开始到结束,替换成新的字符串* 同样也是左闭右开*/sb1.replace(1, 3, "ABC"); // aABCdefgSystem.out.println(sb1);}
}
  1. reverse():反转方法
public class test {public static void main(String[] args) {StringBuilder sb1 = new StringBuilder("abcdefg");sb1.reverse();System.out.println(sb1); // gfedcba}
}
  1. setCharAt(int index, char ch):设置某个位置为指定的字符
public class test {public static void main(String[] args) {StringBuilder sb1 = new StringBuilder("abcdefg");sb1.setCharAt(0, 'A');System.out.println(sb1); // Abcdefg}
}
  1. setLength(int newLength):设置新的长度
public class test {public static void main(String[] args) {StringBuilder sb1 = new StringBuilder("abcdefg");sb1.setLength(3);System.out.println(sb1); // abc}
}

剩下的一些方法,在用到的时候看一下即可,都不是很难。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com