一、String类及常用方法
-
String: 字符串,使用一对“ ”引起来表示。
-
String声明为final的,不可被继承。
-
String实现的接口
-
Serializable接口:表示字符串是支持序列化的。
- Compara接口:表示String是可以比较大小的。
-
-
String内部定义了
final char[ ] value
用于存储字符串内容。 -
String是不可变的字符序列。**简称:**不可变性
体现:
1. 当对字符串重新赋值时,需要重新指定内存区域赋值,不能使用原有value进行赋值。2. 当对现有字符串进行拼接操作时,也如此。 3. 当调用String的replace( )方法修改指定字符或字符串时,也如此。
public static void main(String[] args) {
String s1="abc";
String s2=s1.replace('a', 'm');
System.out.println(s1);//abc
System.out.println(s2);//mbc
}
-
通过字面量的方式(区别与new)给一个字符串赋值,此时的字符串值声明在字符串常量池中。
String s1="abc";//字面量的定义方式
-
字符串常量池中不会存储相同内容的字符串。
-
String对象创建方式及几种简单构造器
==============================String对象的创建=========================================
String str = "hello";
//本质上this.value = new char[0];
String s1 = new String();
//this.value = original.value;
String s2 = new String(String original);
//this.value = Arrays. copyOf(value,value.length) ;
String s3 = new String(char[] a);
String s4 = new String(char[] a,int startIndex,int count) ;
- String两种实例化方式,字面量定义与new+构造器定义字符串区别
-
intern()方法与全局常量字符串
String s1="hello"; String s2="world"; String s3="hello"+"world"; String s4=s1+"world"; System.out.println(s3==s4);//false String s5=s4.intern();//返回给s5常量池中的数据"helloworld"地址 System.out.println(s3==s5);//true final String s6="hello";//全局常量 String s7=s6+"world"; System.out.println(s3==s7)//true
结论:
常量与常量的拼接结果在常量池,且常量池中不会存在相同的内容常量。
只要其中一个是变量,结果就在堆中。
如果拼接的结果调用intern()方法,返回值就在常量池中。
- String类常用方法
int length() //返回字符串长度
char charAt(int index)//返回某索引处的字符
boolean isEmpty()//判断是否为空字符串
String toLowerCase()//将String中所有字符转换为小写
String toUpperCase()//将String中所有字符转换为大写
String trim()//返回字符串的副本,忽略前导空格和尾部空格
boolean equals(Object obj)//比较字符串内容是否相同
boolean equalslgnoreCase(String anotherString)//忽略大小写比较内容是否相同
String concat(String str)//将参数字符串连接到该字符串尾部,等价于“+”
int compareTo(String anotherString)//比较两个字符串的大小,一个一个字符比较ASII码返回差值
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值序列(参数串s)时,返回true
int indexOf(String str)//返回指定子字符串在此字符串中第一次出现的索引
int indexOf(String str,int formIndex)//从指定的索引开始,返回指定字符串在此字符串中第一次出现的索引
int lastIndexOf(String str)//返回指定子字符串在此字符串中最后出现的索引
int lastIndexOf(String str,int formIndex)//从指定的索引反向搜索,返回指定字符串在此字符串中最后一次出现的索引
注:如未找到,则返回-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个,如果超过了,剩下的全部都放在最后一个元素中
正则表达式
10.JVM中字符串常量池存放位置说明:
jdk 1.6 (jdk 6.0 ,java 6.0):字符串常量池存储在方法区(永久区)
jdk 1.7:字符串常量池存储在堆空间
jdk 1.8:字符串常量池存储在方法区(元空间)
二、String类与其他结构之间的转换
1. String类与基本数据类型,包装类之间的转换
public void test01(){
String str1 = "123";
String str4 = "123";
//int num = (int)str1;不能直接强转,两者没有继承关系。
int num = Integer.parseInt(str1);//num=123
String str2 = String.valueOf(num);//str2="123"
String str3=num+"";//str3="123"
System.out.println(str1==str4);//true
System.out.println(str1==str2);//false
System.out.println(str2==str3);//false
System.out.println(str1==str3);//false
}
2. String与char[ ]之间的转换
public void test02(){
String str1 = "123abc";
char[] charArray = str1.toCharArray();
for (int i = 0; i <charArray.length; i++) {
System.out.println(charArray[i]);//1 2 3 a b c
}
char[] arr = {'h', 'e', 'l', 'l', 'o'};
String str2 = new String(arr);//使用String字符数组构造器
System.out.println(str2);//hello
}
3. String与byte[ ]之间的转化
public void test03() throws UnsupportedEncodingException {
String str1 = "123abc中国";
byte[] bytes = str1.getBytes();
// 1 2 3 a b c 中 国 默认使用utf-8编码集
//[49, 50, 51, 97, 98, 99, -28, -72, -83, -27, -101, -67]
System.out.println(Arrays.toString(bytes));
//使用gbk编码集编码 需抛出不支持编码集异常
byte[] gbks = str1.getBytes("gbk");
System.out.println(Arrays.toString(gbks));// 中 国
// [49, 50, 51, 97, 98, 99, -42, -48, -71, -6]
/*
* 编码:字符串,音视频。。。--->字节
* 解码:字节--->字符串,音视频。。。
* */
String str2 = new String(bytes);//默认使用utf-8编码集解码
System.out.println(str2);//123abc中国
String str3 = new String(gbks);//编码集与解码集不一致,出现乱码
System.out.println(str3);//123abc�й�
String str4 = new String(gbks,"gbk");//使用gbk编码集解码
System.out.println(str3);//123abc中国
}
三、StringBuffer and StringBuilder
1. String StringBuffer StringBuilder 三者异同
String:不可变的字符序列。
StringBuffer:可变的字符序列,线程安全的,但效率低。(synchronized)
StringBuilder:可变的字符序列,线程不安全的,效率比较高。(JDK5.0新增)
同:底层使用char[ ] 存储。
public void test(){
String str = new String();//char[] value = new char[0];
String str1 = new String("abc");//char[] value = new char[]{'a','b','c'};
StringBuffer sb1 = new StringBuffer();//char[] value = new char[16];
/*stringbuffer.length()-->count(append字符的个数)*/
System.out.println(sb1.length());//0
sb1.append('a');
sb1.append("bc");
StringBuffer sb2 = new StringBuffer("abc");//char[] value = new char["abc".length+16];
System.out.println(sb1.length());//3
System.out.println(sb2.length());//3
}
//指定大小创建构造器
//建议使用:StringBuffer(int capacity)或StringBuilder(int capacity)
扩容机制:如果要添加的数据底层数组装不下了,那就需要扩容底层数组。默认情况下,扩容为原来容量的2倍+2((value.length<<1)+2),同时将原有的数组元素复制到新的数组中。如果添加的数据比扩容数量还大,则将扩容插入数据大小。。。等等
2. StringBuffer,StringBuilder常用方法
//以StringBuffer为例
StringBuffer qppend(x/"xxx"/true...)//提供了很多append()方法,用于进行字符串的拼接
StringBuffer delete(int start,int end)//删除指定位置内容
StringBuffer replace(int start,int end,String str)//把[start,end)位置替换为str
StringBuffer insert(int offset,"xxx")//在指定位置插入xxx
StringBuffer reverse()//把当前字符序列逆转
public int indexOf(String str)//返回索引
public String substring(int start,int end)//返回索引子字符串
public int length()//返回长度
public char charAt(int n)//返回索引处字符
public void setCharAt(int n,char ch)//将指定位置改为指定字符
3. String StringBuffer StringBuilder效率对比
@Test
public void test3(){
//初始设置
long startTime = 0L;
long endTime = 0L;
String text = "";
StringBuffer buffer = new StringBuffer("");
StringBuilder builder = new StringBuilder("");
//开始对比
startTime = System.currentTimeMillis();
for (int i = 0; i < 20000; i++) {
buffer.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println("StringBuffer的执行时间:" + (endTime - startTime));
startTime = System.currentTimeMillis();
for (int i = 0; i < 20000; i++) {
builder.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println("StringBuilder的执行时间:" + (endTime - startTime));
startTime = System.currentTimeMillis();
for (int i = 0; i < 20000; i++) {
text = text + i;
}
endTime = System.currentTimeMillis();
System.out.println("String的执行时间:" + (endTime - startTime));
}
Test:
StringBuffer的执行时间:12
StringBuilder的执行时间:3
String的执行时间:1919