目录
2.更换使用StringBulider或者StringBuffer类
一.创建字符串的四种方式
方式一:直接赋值法
String str ="HelloWord";
方式二:通过构造方法产生对象
String str = new String("HelloWord");
方式三:通过字符数组产生对象
char[] data = new char[]{'a','b','c'}
方式四:通过String的静态方法valueOf(任意数据类型)=>转为字符串
String str = String.valueOf(10);
字面量:直接写出来的数值就称为字面量
10-> int字面量 10.1->double字面量
true->boolean字面量 "abc"->String字面量
String 也是引用类型. String str = "Hello"; 这样的代码内存布局如下
再让 String str1= str;内存会发生下面的变化
如果修改str1的值 那str会发生变换吗;
str1=“word”;先用代码实现一下
通过实现代码,我们发现str不会随着str1的改变而去改变,再来看一看内存中是怎样变化的;
其实“str1=“word”;”并不是修改指令,只是让str1 指向了一个新的对象“word”。
二:字符串比较相等
所有引用数据类型在比较是否相等时,使用equals方法比较;
引用数据类型使用“==”比较的依然是地址是否相等。
至于str==str1执行结果为false,代表 str 和 str1 的地址并不相同,想了解对象在内存中是如何生成,就要了解字符串常量池。
三.字符串常量池
1.直接赋值法
当使用直接赋值法产生字符串对象时,JVM会维护一个字符串的常量池,若该对象在堆中还不存在,测产生一个新的字符串对象加入字符串的常量池中。
再次使用直接赋值法产生字符串对象时,JVM发现该引用指向的内容在常量池中已经存在了,则在此时不再新建字符串对象,而是复用已有对象。
string str = “hello word” ;//产生一个新的字符串对象加入字符串的常量池中
后面 String str1="hello word"; String str2 ="hello word";因为引用指向的内容(hello word)在常量池中已经存在了,直接复用常量池中已有对象。
2.采用构造方法
String str = new String("helloword");
代码从左向右执行,字符串字面量"helloword"第一次出现,所以在常量池中储存"helloword",sui随后有new会在堆中开辟一个新的空间存放字符串“helloword”,引用str指向新开辟的堆内存的地址。
String str1="helloword"; 此时字符串常量池中已经存在引用指向的内容了,直接复用常量池中的''helloword'';
通过上面构造方法发现会开辟两个堆内存空间,并且其中一块堆内存将成为垃圾空间;同一个字符串可能被储存多次,比较浪费空间。
我们可以使用String的intern方法来手动把String对象加入到字符串常量池中。
intern使用规则:
调用intern方法会将当前字符串引用指向的对象保存到字符串常量池中。
1.如当前常量池中已经存在了该对象,则不会产生新的对象,返回常量池的String对象。
使用构造方法创建字符串对象时常量池中已经有了“hello”,所以随后的intern方法不会再产生新的对象,str1指向的就为常量池中的对象;输出结果就为false。
str.intern();指向的为常量池中的“hello”;此时str = str.intren();使str也指向了常量池中的“hello”;
所以输出结果为true;
2.若常量池不存在该对象,则将该对象入池,返回入池的地址。
当使用构造方法创建对象时,data还是字符串数组,不是字符串对象。
四,字符串的不可变性
所谓的字符串不可变指的是字符串对象的内容不能变,而不是符串引用不能变。
这里不可变指的是“hello”“word”“!!!”,这些字符对象一旦声明后就无法修改其内容。
为什么String的对象不可以修改内容
字符串其实就是一个字符数组->char[],字符串保存的值实际上在数组中保存,String类的外部拿不到这个value数组。
五.修改字符串的内容;
1.在运行时通过反射破坏value数组的封装
2.更换使用StringBulider或者StringBuffer类
StringBulider类
StringBulider类与String类是两个独立的类,StringBulider类就是为了解决字符串的拼接问题产生的;StringBulider类的对象是可以修改内容的。
如果要频繁进行字符串的拼接,使用StringBuilder类的append方法
字符串的反转操作,reverse();
删除指定范围的数据,delete(int start,int end);
区间为左闭右开
插入操作,insert(int start,各种数据类类型)
将新元素插入当前sb对象,插入后新元素的索引为start;
StringBlider类与String类的互相转换
StringBulider——>String :调用toString()方法
String——>StringBulider :使用StringBulider类的构造方法或者append方法
StringBuffer类的使用操作与StringBulider类一致;
*StringBuffer类、StringBulider类、string类的区别:
1.String类的对象无法修改,StringBulider类和StringBuffer类的对象内容可以修改。
2.StringBuffer类是线程安全的操作,性能较差;StringBulider是线程不安全,性能较高。
六.字符串其他常见操作
1.字符串的比较
1).equals() :区分大小写的比较
2).aqualsIanoreCase:不区分大小写的比较
3).compareTo :比较两个字符串的大小关系
按照“字典序”排列字符串,就是按照字符串内部字符的ASCII码大小排序;
A:65 a:97
2.字符与字符串的相互转化
字符串内部就是使用字符数组来存储的。
char——>String 通过String类的构造方法
将字符数组的部分内容转为字符串对象
String——>char
1.取出字符串中指定索引的字符
2.将字符串中的内容转为字符数组
此时产生了一个新的字符数组,将字符串的内容复制过去,原先的字符串还是没有变。
*设计程序判断一个字符串的对象是由纯数字组成的?
3.字符串和字节的互相转换
将字符串保存到文件中或是通过网络传输都要用到字节数组
String——>byte[]
将字符串以字节数组的形式返回
byte——>String
1.将字节数组变为字符串
2.将部分字节数组中的内容变为字符串
4.字符串的查找操作
1).判断一个字符串是否存在
2).判断是否以指定字符串开头
3).判断是否以指定字符串结尾
5.字符串的替换操作
6.字符串的拆分操作
1.spilt(String regex) 将字符串全部拆分
2.spilt(String regex , int limit) 将字符串部分拆分,该数组长度就是limit极限
若拆分标志是特殊字符则需要转义处理,
7.字符串的截取操作
1.substring(int beginIndex) 从指定索引截取到结尾
2.substring(int beginIndex , int endIndex) 截取部分内容
并没有改变原先的字符串只是产生一个新的字符串。