String
String的特性
- String类:代表字符串。Java 程序中的所有字符串字面值(如 “abc” )都作 为此类的实例实现。
- String是一个final类,代表不可变的字符序列。
- 字符串是常量,用双引号引起来表示。它们的值在创建之后不能更改。
- String对象的字符内容是存储在一个字符数组value[]中的。
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使用陷阱
String s1 = "a";
说明:在字符串常量池中创建了一个字面量为"a"的字符串。
s1 = s1 + "b";
说明:实际上原来的“a”字符串对象已经丢弃了,现在在堆空间中产生了一个字符
串s1+"b"(也就是"ab")。如果多次执行这些改变串内容的操作,会导致大量副本
字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大影响
程序的性能。
String s2 = "ab";
说明:直接在字符串常量池中创建一个字面量为"ab"的字符串。
String s3 = "a" + "b";
说明:s3指向字符串常量池中已经创建的"ab"的字符串。
String s4 = s1.intern();
说明:堆空间的s1对象在调用intern()之后,会将常量池中已经存在的"ab"字符串
赋值给s4。
字符串与其他类型的转换
-
字符串→基本数据类型、包装类
- Integer包装类的public static int parselnt(String s):可以将由“数字”字符组成的字符串转换为整型。
- 类似地,使用java.lang包中的Byte、Short、Long、Float、Double类调相应的类方法可以将由“数字”字符组成的字符串,转化为相应的基本数据类型。
-
基本数据类型、包装类→字符串
- 调用String类的public String valueOf(int n)可将int型转换为字符串
- 相应的valueOf(byte b)、valueOf(long l)、valueOf(float f)、valueOf(doubled)、 valueOf(boolean b)可由参数的相应类型到字符串的转换
-
字符串→基本数据类型、包装类
public static int parse***(String s)
public class StringTest2 {
public static void main(String[] args) {
int a = 3;
//Integer a = 3; 也可以
System.out.println(Integer.valueOf(a));
String b = "4";
System.out.println(Integer.parseInt(b));
}
}
- String --> char[]:调用String的toCharArray()
- char[] --> String:调用String的构造器
public class StringTest2 {
public static void main(String[] args) {
String str1 = "abc123";
char[] charArray = str1.toCharArray();
for (int i = 0; i < charArray.length; i++) {
System.out.println(charArray[i]);
}
char[] arr = new char[]{'h','e','l','l','o'};
String str2 = new String(arr);
System.out.println(str2);
}
}
String 与 byte[]之间的转换
String --> byte[]:调用String的getBytes()
public class StringTest2 {
public static void main(String[] args) {
String str1 = "abc123";
byte[] bytes = str1.getBytes(); //使用默认的字符集,进行转换
System.out.println(Arrays.toString(bytes));
String str2 = new String(bytes);
System.out.println(str2);
byte[] bytes = str1.getBytes();
}
}
String,StringBuffer,StringBuilder
String:不可变的字符序列:底层使用char[]存储
StringBuffer:可变的字符序列:线程安全,效率低:底层使用char[]存储
StringBuilder:可变的字符序列:jdk5.0新增的,线程不安全,效率高:底层使用char[]存储
//源码里面怎么创建的:
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];底层创建了16个长度的数组
sb1.append('a'); //value[0]='a';
sb10append('b'); //value[1]='b';
StringBuffer sb2 = new StringBuffer("abc"); //char[] value = new char["abc".length() + 13]
//
//问题1:System.out.println(sb2.length());//3
//问题2,扩容问题:如果要添加的数据底层数据盛不下了,那就需要扩容底层的数组
//默认情况下,扩容为原来容量的2倍 + 2,同时将原有数组中的元素复制到新的数组中
//指导意义:开发中建议大家使用:StringBuffer(int capacity)或 StringBuilder(int capacity)
//速度从大到小:String,StringBuffer,StringBuilder
StringBuffer
StringBuffer类不同于String,其对象必须使用构造器生成。有三个构造器:
- StringBuffer():初始容量为16的字符串缓冲区
- StringBuffer(int size):构造指定容量的字符串缓冲区
- StringBuffer(String str):将内容初始化为指定字符串内容
StringBuffer类的常用方法
StringBuffer append(xxx):提供了很多的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() :把当前字符序列逆转
- 当append和insert时,如果原来value数组长度不够,可扩容。
- 如上这些方法支持方法链操作。
- 方法链的原理:
StringBuilder类
- StringBuilder 和 StringBuffer 非常类似,均代表可变的字符序列,而且 提供相关功能的方法也一样
- 面试题:对比String、StringBuffer、StringBuilder
- String(JDK1.0):不可变字符序列
- StringBuffer(JDK1.0):可变字符序列、效率低、线程安全
- StringBuilder(JDK 5.0):可变字符序列、效率高、线程不安全
注意:作为参数传递的话,方法内部String不会改变其值,StringBuffer和StringBuilder 会改变其值。