一、介绍
String | Serializable | 实现它,String可以串行化,可以在网络上传输 |
---|---|---|
Comparable | String对象可以相互比较 | |
CharSequence | ||
Object |
String
class Main{
public static void main(String[] args) {
//1.String 对象用于保存字符串,也就是一组字符序列
//2."jack"字符串常量,双引号括起的字符串序列
String name = "Jack";
//3.字符串使用Unicode字符编码,一个字符(不区分字母还是汉字)占两个字节。
//4.String是final类,不能被其他类继承
//5.String 有属性 private final char value[];用于存放字符串内容
//7.一定要注意:value 是一个final类型,不可以修改(地址不可修改,不可指向新的对象可以修改值)
}
}
String类较常用构造器(其它看手册):
String s1 = new String();
String s2 = new String(String original);
String s3 = new String(char[]a);
String s4 = new String(char[]] a,int startlndex,int count)
二、创建刨析
易错分析
String中重写了Object中的equals方法,并重定义了它的功能,将其的地址比较改为了值比较,它改成了比较字符串是否相同
思考一:
//先在常量池里面创建了abc
//然后a指向它,同时b也指向它
//所以a,b的地址相同
String a = "abc";
String b = "abc";
System.out.printIn(a.equals(b));//T
System.out.println(a==b);
思考二
String a ="hsp"; //a 指向 常量池的“hsp'
String b =new String("hsp");//b 指向堆中对象
System.out.println(a.equals(b)); //T
System.out.println(a==b); //F
System.out.println(a==b.intern());//T //intern方法自己先查看API
System.out.println(b==b.intern());//F
知识点:
当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用equals(object)方法确定),则返回池中的字符串。
否则,将此 String 对象添加到池中,并返回此 String 对象的引用
//解读:b.intern()方法最终返回的是常量池的地址(对象)
思考三
//只创建一个对象
String a = "hello" + "world";
//创建了三个对象,如下图所示
//1.先创建一个 StringBuilder sb = stringBuilder()
//2.执行 sb.append("hello");
//3. sb.append("abc");
//4.string c= sb.tostring()
//最后其实是c指向堆中的对象(String)value[]->池中"helloabc"
String a = "hello";
String b = "word";
String c = a + b;
思考四
public class Test1 {
String str = new String("hsp");
final char[] ch = { 'j', 'a','v','a'};
public void change(String str, char ch[]) {
str ="java";
ch[o] = 'h';
}
public static void main(Stringl] args){
Test1 ex = new Test1();
//调用一个方法会产生一个新栈
ex.change(ex.str, ex.ch);
System.outprint(ex.str + "and ");
System.out.println(ex.ch);
}
}
三、String常用方法
public Main{
public static void main(String[] args){
//1.equals 区分大小写,判断内容是否相等
//2.equalslgnoreCase 忽略大小写的判断内容是否相等
//3.length() 获取字符的个数,字符串的长度
//4. indexOf 获取字符在字符串中第1次出现的索引,索引从0开始,如果找不到,返回-1
String s1 = "wer@eeyyy@g@";
int index = s1.indexOf('@');
System.out.println(index);//3
//也可以是字符串
System.out.println(s1.indexOf("er"));
//5.lastIndexOf 获取字符在字符串中最后1次出现的索引,索引从0开始,如找不到,返回-1
String s1 = "wer@eeyyy@g@";
int index = s1.lastIndexOf('@');
System.out.println(index);//11
//6.substring 截取指定范围的子串
String name = "hello,张三";
//下面name.substring(6)从索引6开始截取后面所有的内容
System.out.println(name.substring(6));//截取后面的字符//张三
//name.substring(0,5)表示从索引2开始截取,截取5个字符
System.out.println(name.substring(2,5));//llo,张
//7.trim 去前后空格
//8.charAt 获取某索引处的字符,注意不能使用Str[index]这种方式
//9.toUpperCase转换成大写
String s = "heLLo";
System.out.println(s.toUpperCase());
//10.toLowerCase转换成小写
System.out.println(s.toLowerCase());
//11.concat拼接字符串
String s1 = "宝玉”;
s1 = s1.concat("林黛玉”).concat("薛宝钗”).concat("together");
System.out.println(s1);
//12.replace 替换字符串中的字符
String s1 =“宝玉 and 薛宝钗 薛宝钗 薛宝钗”;
//将s1中所有的 林黛玉 全部替换成 薛宝钗
s1 = s1.replace("林黛玉”,“薛宝钗”);
// s1.replace()方法执行后,返回的结果才是替换过的。
// 注意对 s1没有任何影响
System.out.println(s1);
//13.split 分割字符串,
//对于某些分割字符,我们需要 转义比如\等
String poem ="锄禾曰当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦";
String split = poem.split(",");
String poem = "E:\\aaa\\bbb";
String[] split = poem.split("\\|");
String[] split= poem.split("\\\\\");
String[] split = poem.split("\\\\");
for(int i=0;i<split.length;i++){
System.out.printIn(split[i]);
}
//14.toCharArray 转换成字符数组
String s= "happy";
char[] chs = s.tocharArray();
for(int i = 0;i < chs.length;i++){
System.out.println(chs[i]);
}
//15.compareTo 比较两个字符串的大小,如果前者大,
// 则返回正数,后者大,则返回负数,如果相等,返回0
String a = "jchn";
String b = "jack";
System.out.println(a.compareTo(b));//返回值是'c' - 'a'= 2的值
String a = "jac";// len = 3
String b = "jack";// len = 4
System.out.println(a.compareTo(b));//返回值-1
//16.format 格式字符串
/*占位符有:
*%s 字符串 %c 字符 %d 整型 %.2f 浮点型
*/
String name =:"john";
int age = 10;
double score = 9.3 / 3;
char gender ='男';
//将所有的信息都拼接在一个字符串.
String info = "我的姓名是"+ name +"年龄是"+ age +",成绩是"+ score +"性别是"+ gender + “希望大家!”;
System.out.println(info);
String info = String.format("我的姓名是%s年龄是%d,成绩是%.2f性别是%c.希望大家喜我!",name,age,score,gender);
}
}
四、StringBuffer类
1.基本介绍
StringBuffer代表可变的字符序列,可以对字符串内容进行增删
很多方法与但StringBuffer是可变长度
StringBuffer是一个容器
public class Main{
public static void main(String[] args){
//1.StringBuffer 的直接父类 是 AbstractStringBuilder
//2.StringBuffer 实现了Serializable,即StringBuffer的对象可以串行化
//3.在父类中 AbstractStringBuilder 有属性 char[] value,不是final,该value数组存放字符串内容,引出存放在堆中
//4.StringBuffer 是一个 final 类,不能被继承
//5.因为StringBuffer 字符内容是 存在 char[] value,所有在变化(增加/删除)
// 不用每次都更换地址(即创建新对象),所以效率高于String
StringBuffer stringBuffer = new StringBuffer("hello");
}
}
1)String 保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更改地址,效率较低 //private final char value[];
2)StringBuffer 保存的是字符串变量,里面的值可以更改,每次StringBuffer的更新实际上可以更新内容,不用更新地址,效率较高
//char[ ] value; // 这个放在堆。
2.StringBuffer的构造器
StringBuffer()
构造一个其中不带字符的字符串缓冲区,其初始容量为16个字符。
StringBuffer(CharSequence seq)
public java.lang.StringBuilder(CharSequence seq)构造一个字符串缓冲区,它包含与指定的Charsequence 相同的字符。
StringBuffer(int capacity)//capacity[容量]
构造一个不带字符,但具有指定初始容量的字符串缓冲区。即对char 大小进行指定
StringBuffer(String str)
构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容。
3.StringBuffer类常见方法
1)增 append
2)删 delete(start,end)
3)改 replace(start,end,string) //将start----end 间的内容替换掉,不含end
4)查 indexOf //查找子串在字符串第1次出现的索引,如果找不到返回-1
5)插 insert(9,"张梅")
6)获取长度 length()
五、StringBuilder类
1.基本介绍
1)一个可变的字符序列。此类提供一个与StringBuffer兼容的API,但不保证同步(StringBuilder不是线程安全)。
该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候。如果可能,建议优先采用该类,
因为在大多数实现中,它比StringBuffer要快。
2)在StringBuilder上主要操作是 appand和insert方法,可重载这些方法,以接受任意类型的数据。
public class stringBuilder01 {
public static void main(string[] args){
//1.StringBuilder 继承 AbstractstringBuilder 类
//2.实现了 Serializable,说明StringBuilder对象是可以串行化(对象可以网络传输,可以保存到文件)
//3.StringBuilder 是final类,不能被继承
//4.StringBuilder 对象字符序列仍然是存放在其父类 AbstractstringBuilder的 char[] value;
//因此,字符序列是堆中
//5.stringBuilder 的方法,没有做互斥的处理,没有synchronized 关键字,因此在单线程的情况下使用stringBuilder
StringBuilder stringBuilder = new stringBuilder();
}
}
2.StringBuilder应用
String、StringBuffer 和StringBuilder的比较
1)StringBuilder 和 StringBuffer 非常类似,均代表可变的字符序列,而且方法也一样
2)String:不可变字符序列,效率低,但是复用率高
3)StringBuffer:可变字符序列、效率较高(增删)、线程安全,看源码
4)StringBuilder:可变字符序列、效率最高、线程不安全
5)String使用注意说明:
string s="a";//创建了一个字符串
s += "b";//实际上原来的"a"字符串对象已经丢弃了,现在又产生了一个字符串s +"b"(也就是"ab")。
如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大影响程序的性能 =>结论:如果我们对String 做大量修改,不要使用String。
效率:StringBuilder > StringBuffer > String
六、使用的原则,结论
1.如果字符串存在大量的修改操作,一般使用 StringBuffer 或StringBuilder
2.如果字符串存在大量的修改操作,并在单线程的情况,使用 StringBuilder
3.如果字符串存在大量的修改操作,并在多线程的情况,使用 StringBuffer
4.如果我们字符串很少修改,被多个对象引用,使用String,比如配置信息等
StringBuilder 的方法使用和 StringBuffer 一样,不再说