String类
特点:
双引号括起来的是字符串,也叫字符序列。"abc"
字符串 是常量,一旦创建就不能改变
构造方法:
public String():无参构造
public String(byte[] bytes):有参的,byte数组
public String(byte[] bytes,int offset,int length)
public String(char[] value):有参的,char数组
public String(char[] value,int offset,int count)
public String(String original)
String str1 = new String();// ""表示空字符串
主要解释一下String类型的 不可改变性(常量)是怎么回事
String s = "hello";
s += "world";// s = s + w "helloworld"
/**
* s 第一次会在常量池中 判断是否存在"hello"
* 如果不存在,就在常量池中创建"hello"并将地址传递给堆内存上
* 如果存在,就直接返回给堆内存
* 第二次 s变量,会在常量池中,判断,是否存在"world"字符串常量
* 如果不存在,就在常量池中创建"world "并将地址传递给堆内存上
* 如果存在,就直接返回给堆内存
* 第三次s变量 会在常量池中,判断,是否存在拼接后的结果"helloworld"字符串常量
* 如果不存在,就在常量池中创建"helloworld"并将地址传递给堆内存上
* 如果存在,就直接返回给堆内存
*/
System.out.println(s);
String s = new String(“hello”)和String s = “hello”;的区别?
String str1 = "hello";// String str1 = new String("hello");
String str2 = new String("hello");
// 首先在常量池中,查找"hello"字符串常量有没有存在
System.out.println(str1 == str2);// false
String str3 = "hello";// 有没有在堆上创建 对象,没有,直接常量池里面找
System.out.println(str1 == str3);// true
String str4 = new String("hello");
// new 出来的东西,永远都是新的,独一无二的
System.out.println(str2 == str4);// false
String 的equals()重写了Object的equals()方法:
实现的规则:
1:如果自己和自己比较(堆内存地址和堆内存地址比较),就直接true
2:比较字符串的长度是否相等
3:比较字符串的每一个字符是否相等
StringBuffer 类
可变的字符串
线程安全,“加了一把锁,排队写操作”效率会变慢
构造方法:
public StringBuffer():构造一个其中不带字符的字符串缓冲区,其初始容量为 16 个字符。
public StringBuffer(int capacity):指定 初始容量大小
public StringBuffer(String str)
添加功能
public StringBuffer append(String str):按顺序排队
public StringBuffer insert(int offset,String str):插队
删除功能
public StringBuffer deleteCharAt(int index)
public StringBuffer delete(int start,int end)
替换功能
public StringBuffer replace(int start,int end,String str)
反转功能
public StringBuffer reverse()
StringBuffer sb = new StringBuffer();
System.out.println(sb.capacity());
sb.append("hello").append("a").append("world");
sb.append("abcd");
// 相当于 "hello" + "a" + "world" + "abcd";
System.out.println(sb);
System.out.println(sb.toString());
// 打印一个对象,其实跟打印一个对象的toString()是一样的
// 所以,我们常常省略toString方法,直接打印对象
StringBuffer 的length()方法和capacity()方法区别?
StringBuffer 内部维护了一个char数组,给定capacity个大小
length()方法返回的是数组具体存储的 内容长度
// 删除
sb.deleteCharAt(0).deleteCharAt(1).deleteCharAt(2);
sb.delete(2, 5).delete(1, 2);
// "abc" "cba" 数组的反转
System.out.println(sb.reverse().append("10").delete(1, 2));
String 和StringBuffer 作为形式参数传递给方法
// 测试 StringBuffer 作为形式参数传递的问题
private static void Change(StringBuffer x, StringBuffer y) { // 形式参数
// 改变形式参数的值
x = y;// 把y引用的地址值 赋值给x 跟sb1没有任何关系,也没有sb1原有的对象的值
y.append(x);// 将y引用指向的对象的具体内容,改变了。此时,x,y指向是同一个对象
// 测试 String作为形式参数传递的问题
// String是引用类型,但是是一种特殊的引用类型,把String作为形式参数传递的时候
// 我们把String 看做是 “基本数据类型”来处理
private static void Change(String str1, String str2) {
// 改变形式参数的值
str1 = str2;
str2 = str1 + str2;
}
StringBuilder 类
特点:
1:是一个可变的字符串序列
2:不同步的(线程不安全的)效率高,有可能产生脏数据
3:StringBulider 与StringBuffer 是兼容的
4:在大多数情况下(单线程的情况下),使用StringBuilder
String,StringBuffer,StringBuilder的区别
1:String 不可变的字符序列,而StringBuffer,StringBuilder 都是可变的字符序列
2:StringBuffer,StringBuilder 的区别:
StringBuffer的线程是安全的,效率低,数据安全
StringBuilder的线程是不安全的,效率高,数据不安全
StringBuffer和数组的区别?
1:如果是从数据类型的分类来看,这两个都是引用类型
2:如果是用途来讲,两个都是容器,可以存放很多个元素(8种基本数据类型)
3:StringBuffer 类的内部,维护着一个char数组,通过重载append()方法,添加进来元素
都会转换为 char元素存起来,而数组 是一个容器,可以存相同类型的多个元素(8种基本数据类型,自定义类类型等)
4:数组的长度不能变