String
String类代表字符串,字符串不可以变,它们的值在创建后不能被修改。
Why?
我们通过查看String源码可以看到,String底层是由byte[]来实现的,并且有final修饰,这就决定了它的不可变性。
private final byte[] value;
(原来jdk8中String底层是由char[]实现的,jdk9中改为了byte[]。具体可以参考一下jdk9为何要将String的底层实现由char[]改成了byte[]_tc979907461的博客-CSDN博客)
String定义的三种格式
- 直接赋值,例:String str = “abc”;
- 创建对象,例:String str1 = new String(“abc”);
- 拼接对象,例:String str2 = “ab” + “c”; 或者为:String str3 = “ab”;String str4 = str3 + “c”;
String str = "abc";
String str1 = new String("abc");
String str2 = "ab" + "c";
String str3 = "ab";
String str4 = str3 + "c";
System.out.println(str == str1);//false
System.out.println(str == str2);//true
System.out.println(str == str4);//false
System.out.println(str1 == str4);//false
第一次出现,存放在字符串常量池中,返回引用;
第二次出现,直接返回常量池引用,new的String放在堆里。
String的转换:
与字节数组的转换
编码:String --> byte[]:调用String的getBytes()
解码:byte[] --> String:调用String的构造器
****解码时,要求解码使用的字符集必须与编码时使用的字符集一致,否则会出现乱码。
与StringBuffer、StringBuilder之间的转换
String -->StringBuffer、StringBuilder:①调用StringBuffer;②StringBuilder构造器
StringBuffer、StringBuilder -->String:①调用String构造器;②StringBuffer、StringBuilder的toString()
StringBuffer:可变的字符序列;线程安全的,效率低;底层使用char[]存储
StringBuilder:可变的字符序列;jdk5.0新增的,线程不安全的,效率高;底层使用char[]存储
三者的执行效率:
从高到低排列:StringBuilder > StringBuffer > String
String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。
*String:适用于少量的字符串操作的情况
**StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
**StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
String的常用方法
int length():返回字符串的长度: return value.length
char charAt(int index): 返回某索引处的字符return value[index]
boolean isEmpty():判断是否是空字符串:return value.length == 0
String toLowerCase():使用默认语言环境,将 String 中的所字符转换为小写
String toUpperCase():使用默认语言环境,将 String 中的所字符转换为大写
String trim():返回字符串的副本,忽略前导空白和尾部空白
boolean equals(Object obj):比较字符串的内容是否相同
boolean equalsIgnoreCase(String anotherString):与equals方法类似,忽略大小写
String concat(String str):将指定字符串连接到此字符串的结尾。 等价于用“+”
int compareTo(String anotherString):比较两个字符串的大小
String substring(int beginIndex):返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串。
String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束
boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始
boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始boolean contains(CharSequence s):当且仅当此字符串包含指定的 char 值序列时,返回 true
int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引
int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引
int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索注:indexOf和lastIndexOf方法如果未找到都是返回-1
替换:
String replace(char oldChar, char newChar):返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所 oldChar 得到的。
String replace(CharSequence target, CharSequence replacement):使用指定的字面值替换序列替换此字符串所匹配字面值目标序列的子字符串。
String replaceAll(String regex, String replacement):使用给定的 replacement 替换此字符串所匹配给定的正则表达式的子字符串。
String replaceFirst(String regex, String replacement):使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。
匹配:
boolean matches(String regex):告知此字符串是否匹配给定的正则表达式。
切片:
String[] split(String regex):根据给定正则表达式的匹配拆分此字符串。
String[] split(String regex, int limit):根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中。
StringBuffer、StringBuilder常用方法
增:append(xxx) :将指定的字符串追加到此字符序列。
删:delete(int start,int end) :移除此序列的子字符串中的字符。
改:setCharAt(int n ,char ch) / replace(int start, int end, String str) :使用给定String
中的字符替换此序列的子字符串中的字符。
查:charAt(int n )
插:insert(int offset, xxx) :将xxx
参数的字符串表示形式插入此序列中。
长度:length();reverse():将此字符序列用其反转形式取代。
toString():返回一个与构建起或缓冲器内容相同的字符串
setCharAt(int i, char c):将第 i 个代码单元设置为 c
通过StringBuild的append()的方式添加字符串的效率要远高于使用String的字符串拼接方式:
1、StringBuilder的append()的方式:自始至终只创建过一个StringBuilder的对象,使用String的字符串拼接方式:创建过多个StringBuilder和String的对象。
2、使用String的字符串拼接方式:内存中由于创建了较多的StringBuilder和String的对象,内存占用更大;如果进行GC,需要花费额外的时间。
3、改进的空间:在实际开发中,如果基本确定要前前后后添加的字符串长度不高于某个限定值highLevel的情况下,建议使用构造器实例化。
StringBuilder S = new StringBuilder(highLevel);