String字符串的底层是通过数组实现的。在jdk8之前是使用char类型的数组实现,在jdk9之后是使用byte类型的数组实现
2.1 EQUALS:
equals方法,可以用来判断两个字符串是否相等,我们使用通常的”==“来判断定义的两个字符串是否相等 String str1 = new String(”hello“); String str2 = new String("hello");是不相等的,因为使用等号相当于判断了两个字符串的地址是否相同,但是如果我们使用”==“来判断String str1 ="hello"; String str2 ="hello";结果是true,此处就涉及到了常量池的问题,我们后续详细描述
2.2 charAt(index)
通过输入的下标来获取,字符串中某个下标的字符(因为字符串的底层实现是由数组实现的)
2.3 replace(原来的内容,替换后的内容),repalceFirst(原来的内容,替换后的内容)
将字符串中的某些内容替换为其他的内容
2.4 split(”\\*“)
将字符串分割为字符串数组,一些特殊的字符串例如” * , ^ , | “分割是应该用转义字符 "\\"进行修饰,不然分割结果可能不尽人意
2.5 subString(从什么时候开始截取,什么时候截至)或者是subString(从什么时候开始截取到末尾结束)
2.6 indexof()方法
用来判断字符串中是否有我们想要的字符或字符串;返回值类型为int类型
indexof(String)返回该字符串的开始下表
indexof(String,int)从int位置开始查找String字符串并且返回该字符串的开始下标
indexof(ASCII)按照ASCII码的形式查找索引值并返回 A的ASCII码为65 a的ASCII码值为97
jdk1.8之后将String的底层实现从char类型转变为了byte类型,实际上就是i为了节省String占用的jvm内存空间
jdk1.7中的元空间:
jdk1.8中的元空间:
String字符串的一些特性:
1.String是一个final类,代表不可变的字符序列
2.字符串是不可变的,一个字符串对象一旦被分配,其内容是不可变的
String str = "hello"; str = "world";实际上是创建了两个字符串对象都创建在字符串常量池中
String定义对象:
1.String str1 = "hello";
2.String str2 = "hello";
3.String str3 = new String("hello");
当我们使用==判断时,str1 == str2 ;str1!=str3;实际上当我们定义str1=hello时,就自动在字符串常量池创建了一个hello的值
当使用Str2=hello时,将不会在字符串常量池中再次创建hello相当于str1和str2是指向了一个hello
使用方法一创建字符串时:从常量池查看是否有"hello",数据空间,如果有直接指向,如果没有则重新创建,让后面再次定义的指向(2)
使用方法三创建字符串时,先从堆空间中创建空间,里面维护了value属性数组,指向常量池的hell空间,如果常量池没有”“hello”,那么重新创建,如果有直接通过value指向,最终指向的是堆空间中的地址
String的一些问题?
1.试问String str = "hello" + "world";底层创建了几个对象?
答案是一个;编译器会自动优化代码,将两个字符串合并为一个字符串然后保存在字符串常量池中
2.试问String str = "a"; String str1 = "b"; String str2 = str+str1;创建了几个对象?3个
我们知道,在调用String str = "a"; String str1 = "b";时会首先创建两个对象,当我们再次使用String str2 = str+str1时,实际上就是使用了StringBuilder类中的append方法,具体实现为
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(str);
stringBuilder.append(str1);
String s = stringBuilder.toString();
3.接上题,试问如果我再次定义,,,,String str3 = "ab";试问,?str3==str2?
答案是不相同,因为调用StringBuilder中的toString方法时,会new一个String对象而STR3指向字符串常量池,Str2指向堆空间的value