欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

android StringBuilder的Capacity的使用

发布时间:2024/4/15 编程问答 45 豆豆
生活随笔 收集整理的这篇文章主要介绍了 android StringBuilder的Capacity的使用 小编觉得挺不错的,现在分享给大家,帮大家做个参考.




今天,简单讲讲android里如何使用StringBuilder的Capacity属性。


这个其实也很简单,之前我写个关于list的Capacity属性的博客,说到了list的size和Capacity是不一样的。同样,StringBuilder的字符串的长度Length属性和分配的空间Capacity属性也是不一样的。


StringBuilder 类表示可变字符的字符串。

名称

说明

Capacity属性

获取或设置可包含在当前实例所分配的内存中的最大字符数

Length属性

获取或设置当前 StringBuilder 对象的长度

 

StringBuilder Capacity属性的默认值为16

            StringBuilder sb = new StringBuilder();

            Console.WriteLine("Length属性:" + sb.Length + "Capacity属性:" + sb.Capacity);

            Console.ReadLine();

 

 

StringBuilder 对象的Length属性值超过Capacity属性的长度时,StringBuilder 对象内部会重新构造一个字符数组。Capacity属性会变为以前的2倍。例如:Capacity属性的默认值为16,当追加字符串的长度超过16时,Capacity属性会扩充为32

StringBuilder sb = new StringBuilder();

            //追加长度为17的字符串

            sb.Append("01234567890123456");

            Console.WriteLine("Length属性:" + sb.Length + " Capacity属性:" + sb.Capacity);

        Console.ReadLine();

所以为了节省空间的浪费,最好在使用时指定初始化的大小。接下来看看android的源码:

指定初始容量

先来看一下StringBuilder的源码(JDK7)

public final class StringBuilderextends AbstractStringBuilderimplements java.io.Serializable, CharSequence {/** use serialVersionUID for interoperability */static final long serialVersionUID = 4383685877147921099L;/*** Constructs a string builder with no characters in it and an* initial capacity of 16 characters.*/public StringBuilder() {super(16);}/*** Constructs a string builder with no characters in it and an* initial capacity specified by the <code>capacity</code> argument.** @param capacity the initial capacity.* @throws NegativeArraySizeException if the <code>capacity</code>* argument is less than <code>0</code>.*/public StringBuilder(int capacity) {super(capacity);} }


StringBuilder的默认构造方法调用的是父类AbstractStringBuilder 中的AbstractStringBuilder(int capacity)构造方法,如下:

abstract class AbstractStringBuilder implements Appendable, CharSequence {/*** The value is used for character storage.*/char[] value;/*** The count is the number of characters used.*/int count;/*** This no-arg constructor is necessary for serialization of subclasses.*/AbstractStringBuilder() {}/*** Creates an AbstractStringBuilder of the specified capacity.*/AbstractStringBuilder(int capacity) {value = new char[capacity];} }

StringBuilder的内部有一个char[], 在调用StringBuilder的无参构造方法时其内部char[]的默认长度是16。当我们调用StringBuilder的append方法时,其实就是不断的往char[]里填东西的过程。

public StringBuilder append(String str) {super.append(str);return this; }

其中,super.append是调用AbstractStringBuilder 的append(String str)方法,如下:

public AbstractStringBuilder append(String str) {if (str == null) str = "null";int len = str.length();ensureCapacityInternal(count + len);str.getChars(0, len, value, count);count += len;return this; }

StringBuilder的扩容和ArrayList有些类似,具体代码如下:

/*** This method has the same contract as ensureCapacity, but is* never synchronized.*/ private void ensureCapacityInternal(int minimumCapacity) {// overflow-conscious codeif (minimumCapacity - value.length > 0)expandCapacity(minimumCapacity); }/*** This implements the expansion semantics of ensureCapacity with no* size check or synchronization.*/ void expandCapacity(int minimumCapacity) {int newCapacity = value.length * 2 + 2;if (newCapacity - minimumCapacity < 0)newCapacity = minimumCapacity;if (newCapacity < 0) {if (minimumCapacity < 0) // overflowthrow new OutOfMemoryError();newCapacity = Integer.MAX_VALUE;}value = Arrays.copyOf(value, newCapacity); }


StringBuilder默认长度是16,然后,如果要append第17个字符,怎么办?
答案是采用 Arrays.copyOf()成倍复制扩容!
扩容的性能代价是很严重的:一来有数组拷贝的成本,二来原来的char[]也白白浪费了要被GC掉。可以想见,一个129字符长度的字符串,经过了16,32,64, 128四次的复制和丢弃,合共申请了496字符的数组,在高性能场景下,这几乎不能忍。

由此可见,合理设置一个初始值多重要。使用之前先仔细评估一下要保存的字符串最大长度。


简单讲讲,就是StringBuilder在创建时内部分配了一个长度为16的字符数组,每次调用append时,会首先比较新的字符长度与内部数组的大小,如果大于就会进行扩容,扩容的方式是每次是原来容量的2倍。扩容后会将老的数据复制到新的字符数组里,然后将append(sb)里的数据考到新的字符数组里。所以这个是浪费了时间和内存的。所以在知道StringBuilde需要r的最大长度时,最好在使用前就指定初始化的容量Capacity。StringBuffer与StringBuilder都是继承于AbstractStringBuilder,唯一的区别就是StringBuffer的函数上都有synchronized关键字。


android StringBuilder的Capacity的使用就讲完了。


就这么简单。



总结

以上是生活随笔为你收集整理的android StringBuilder的Capacity的使用的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。