读书笔记-String
【String】就是对char[]数组进行封装的对象,由三部分组成:
1, char数组:它是String对象所表示的字符串的超集;
2, 3, offset和count,表示了String对象表示的字符串在char数组中的起始段;
String是特定设计的,包含以下三个特点:
1, 不变性: 不变模式immutable,节省了同步和锁等待的消耗;
2, 针对【常量池】的优化:
变量 内存空间 常量池
String str1 = “abc” ———————>
String str2 = “abc” ———————> abc
String str3 = new String(“abc”) —-> str实例 ———>
注意:str1 == str3.intern()是true;str2, str2直接指向常量池中的”abc”,不拷贝;
3,类的final定义;
String的两个构造方法:
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
String(char[] value, boolean share) {
this.value = value;
}
第一个构造方法会构造全新的char[]数组;
第二个构造方法共享了原来的char[]数组;
【内存泄漏】第二个包可见的共享char[]数组的构造方法会导致内存泄露
这个构造方法是空间换时间的策略(很有可能理解为时间换空间,因为share了空间,但这里大多数情况下是阻止大空间的GC);
调用这个构造方法,会使得原始的char[]数组无法被GC,假如原char[]很大,按新的String对象只引用了其中很小的一部分,这就是subString(begin, end)的潜在风险,因为这个方法使用了这个包可见的构造方法返回了新的共享了旧的char[]数组的String对象:
new String(offset + beginIndex, endIndex-beginIndex, value);
包可见的构造方法,客户代码虽然无法使用,但调用以下方法则间接调用了这个构造方法:
Integer.toString;
Long.toString;
String.concat;
String.replace;
String.subString;
String.toLower;
String.toUpper;
String.valueOf;
比如:
String str = new String(new char[10000000]);
String str2 = str.subString(1, 5);
1000000个字符常驻内存,无法GC,因为5个字符串的使用;
【字符串分割】
String.split提供【正则表达式】分割功能:
“a;b,c:d”.split(“[;|,|:]”);
StringTokenizer是分割字符串的迭代器:
StringTokenizer st = new StringTokenizer(orignalString, “;”);
while(st.hasMoreTokens())
st.nextToken();
用String.indexOf和String.subString来分割字符串:
1 |
while(true) {
String splitStr = null;
int j = orignalStr.indexOf(';');
if(j < 0)
break;
splitStr = orignalStr.subString(0, j);
orignalStr = orignalStr.subString(j + 1); //更新string
|
分割性能:split < StringTokenizer < indexOf&subString
【字符串查找】
indexOf(char c)与charAt(int index)是String互补的方法;
用startWith和endsWith进行字符串;
用charAt实现startWith:
if(origStr.charAt(0) == ‘a’ && origStr.charAt(1) == ‘b’ && origStr.char(2) == ‘c’);
用charAt实现endsWith:
if(origStr.charAt(len - 1) == ‘c’ && origStr.charAt(len - 2) == ‘b’ && origStr.char(len - 3) == ‘a’);
charAt性能高于startWith和endsWith;
【字符串连接 + += concat StringBuilder StringBuffer】
静态字符串(String常量)的连接操作,会在编译期被编译器直接运算优化:
String result = “abc + “and” + “123”; 的性能高于
StringBuilder builder = new StringBuilder();
builder.append(“abc”);
…
因为静态字符串的+操作在编译期就被运算了,运行期只存在”abcand123”一个字符串,并非:
“abc”, “and”, “123”, “abcand”, “abcand123”;
动态字符串(String变量)的连接操作,会在编译期被编译器转换为StringBuilder实现,循环中的局部变量也不例外:
所以,
String str1 = “abc”;
String str2 = “and”;
String str3 = “append”;
String result = str1 + str2 + str3;
的字节码等同于:
String result = (new StringBuilder(String.valueOf(str1))).append(str2).append(str3).toString();
所以,其实用+操作和StringBuilder的性能是一样的 ;
但编译器把+转换为StringBuilder时不够聪明,经常会过多new StringBuilder的对象:
for(int i = 0; i < 10000; i++)
str = str + i;
会被编译器转换为:
for(int i = 0; i < 10000; i++)
str = (new StringBuilder(String.valueOf(str))).append(i).toString();
所以应该显式使用StringBuilder而不是依靠编译器转换为StringBuilder实现:
StringBuilder sb = new StringBuilder();
for(int i = 0; i < 100000; i++)
sb.append(i);
StringBuffer是线程安全的,理论上性能略低于StringBuilder;
StringBuilder和StringBuffer就是变长的char[]数组,跟所有变长数组一样,指定合适capacity可以节省扩容的消耗,提高性能:
StringBuffer(int capacity) StringBuilder(int capacity);
字符串连接的效率:StringBuilder >> concat > +
读书笔记-String的更多相关文章
- 2019.03.19 读书笔记 string与stringbuilder的性能
1 string与stringbuilder 并不是stringbuilder任何时候都在性能上占优势,在少量(大约个位数)的字符串时,并不比普通string操作快. string慢的原因不是stri ...
- [读书笔记]C#学习笔记八:StringBuilder与String详解及参数传递问题剖析
前言 上次在公司开会时有同事分享windebug的知识, 拿的是string字符串Concat拼接 然后用while(true){}死循环的Demo来讲解.其中有提及string操作大量字符串效率低下 ...
- 汉字与区位码互转(天天使用的String存储的是内码),几个常见汉字编码,附有读书笔记
汉=BABA(内码)=-A0A0=2626(区位码)字=D7D6(内码)=-A0A0=5554(区位码) 各种编码查询表:http://bm.kdd.cc/ “啊”字是GB2312之中的第一个汉字,会 ...
- 汉字与区位码互转(天天使用Delphi的String存储的是内码,Windows记事本存储的文件也是内码),几个常见汉字的各种编码,utf8与unicode的编码在线查询,附有读书笔记 good
汉=BABA(内码)=-A0A0=2626(区位码)字=D7D6(内码)=-A0A0=5554(区位码) 各种编码查询表:http://bm.kdd.cc/ 汉(记住它,以后碰到内存里的数值,就会有敏 ...
- 《C#本质论》读书笔记(18)多线程处理
.NET Framework 4.0 看(本质论第3版) .NET Framework 4.5 看(本质论第4版) .NET 4.0为多线程引入了两组新API:TPL(Task Parallel Li ...
- 《C#高级编程》读书笔记
<C#高级编程>读书笔记 C#类型的取值范围 名称 CTS类型 说明 范围 sbyte System.SByte 8位有符号的整数 -128~127(−27−27~27−127−1) sh ...
- js读书笔记
js读书笔记 基本类型的基本函数总结 1. Boolean() 数据类型 转换为true的值 转换为false的值 Boolean true false String 任何非空字符串 "&q ...
- 读书笔记:const和readonly、static readonly 那些事
C#中表示不变的量(常量)的两种形式:const 和readonly const 是静态常量 readonly 是动态常量 严格的来讲:const 应该称为常量 而readonly 则应称为只读变量. ...
- C++ 11学习和掌握 ——《深入理解C++ 11:C++11新特性解析和应用》读书笔记(一)
因为偶然的机会,在图书馆看到<深入理解C++ 11:C++11新特性解析和应用>这本书,大致扫下,受益匪浅,就果断借出来,对于其中的部分内容进行详读并亲自编程测试相关代码,也就有了整理写出 ...
随机推荐
- 10月21日下午PHP常用函数
函数四要素:返回类型 函数名 参数列表 函数体 //最简单的函数定义方式 function Show() { echo "hello"; } Show();//输出结果为he ...
- ajax返回数据类型为XML数据的处理
/*XML:可扩展标记语言 HTML:超文本标记语言 标签:<标签名></标签名> 特点: 1.必须要有一个根 2.标签名自定义 3.对大小写敏感 4.有开始就要有结束 5.同 ...
- python判断字符串
python判断字符串 s为字符串s.isalnum() 所有字符都是数字或者字母s.isalpha() 所有字符都是字母s.isdigit() 所有字符都是数字s.islower() 所有字符都是小 ...
- HTTP2.0介绍
HTTP2.0的所有通信都是在一个TCP连接上完成的. 1.信息传输术语 1.1 流 虚拟信道,可以承载双向消息,每个流都有一个唯一的整数标识符(1.2....N); 1.2 消息 逻辑上的HTTP消 ...
- debian vmwareTools安装总结
1.安装GCC编译器和make: 因为安装VMwareTools需要编译和make所以要先安装它们.安装其实很简单,命令如下: apt-get install gcc make 其实你也可以 ...
- mysql优化--触发器和auto_increment
1.触发器: 触发器的好处:做数据回收站或者做数据关联删除 触发器的坏处:给数据库增加压力,增删改变慢,不利与mysql移到其他数据库会出问题. 触发器建立:只能增删改,查不能建立. 例子1:创建一个 ...
- isArray polyfill
Array.isArray在ie9+浏览器上已经支持,可以放心使用.在垃圾浏览器上,可以说使用如下polyfill(出自MDN) if(!Array.isArray){ Array.isArray = ...
- firefox 提示 setTimeout():useless setTimeout call (missing quotes around argument?) 错误
原来代码: setTimeout(window.parent.refreshNode(id),500);// 500毫秒后,调用父窗口的refreshNode()方法 refreshNode()方法总 ...
- C语言中的EOF和回车不一样
经常我们碰到这样一个C语言问题,例如: 输入一个组整数,按照从小到大排序后输出结果 输入: 1 7 9 2 4 输出: 1 2 4 7 9 这里要用C语言读入一段数的话,如果用 int array ...
- 繁华模拟赛day8 牛栏
/* 标称并没有用到题解中提到的那种奇妙的性质,我们可以证明,正常从1开始走的话,需要T次,如何使这个次数减小?题解中提到一个办法,有一步小于n/t,我们考虑这一步,如果把它匀到左右两步中,则可以减小 ...