1、字符串体系:又被称为不可变的字符序列
理解:描述生活中的一句话,内容可长可短,长到没有上限要求,短到可以没有内容
类型:java.lang.String类
特点:
?? ?1)、不可以被别的类继承;
?? ?2)、字符串底层还是一个数组(字节、字符);
?? ?3)、字符串不可变:字符串的数据内容不可以改变,但是引用地址是可以发生变化的;
?? ?4)、字符串常量数据被存储在字符串常量池中,常量池中不会多次创建相同的数据对象,只会创建一份,给所有引用对象所共享 ==> 好处:节省内存资源;
【拓展】:
java6版本:字符串常量池存在于方法区中
java7版本:字符串常量池被移动到了堆中
java8版本:字符串常量池被移动到了meta data区(元数据区)
//...
常用构造方法:8个,具体的可以自行查看API文档,后面两个下一节再讲
String()?
? ? ? ? ? 初始化一个新创建的 String 对象,使其表示一个空字符序列。
String(String original)?
? ? ? ? ? 初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本。
String(byte[] bytes)?
? ? ? ? ? 通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。
String(byte[] bytes, int offset, int length)?
? ? ? ? ? 通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的 String。
String(char[] value)?
? ? ? ? ? 分配一个新的 String,使其表示字符数组参数中当前包含的字符序列。?
String(char[] value, int offset, int count)?
? ? ? ? ? 分配一个新的 String,它包含取自字符数组参数一个子数组的字符。?
String(StringBuffer buffer)?
? ? ? ? ? 分配一个新的字符串,它包含字符串缓冲区参数中当前包含的字符序列。?
String(StringBuilder builder)?
? ? ? ? ? 分配一个新的字符串,它包含字符串生成器参数中当前包含的字符序列。?
?备注:如果直接打印一个数组,那么会是打印它的地址,此时可以用Arrays.toString()进行转化。
2、常用方法:
/*
1、拼接字符串:
String concat(String str):将指定字符串连接到此字符串的结尾。
*/
s1.concat(s2);
/*
2、切割字符串:
String[] split(String regex):根据给定正则表达式的匹配拆分此字符串。
注意:如果一次都匹配不成功,就将原串作为一个整体存入到String[]中返回
*/
str.split(",");
/*
3、截取字符串:
String substring(int beginIndex):返回一个新的字符串,它是此字符串的一个子字符串。
String substring(int beginIndex, int endIndex):返回一个新字符串,它是此字符串的一个子字符串。
注意:Java语言而言,方法的参数位置同时定义了起始索引和结束索引,绝大多数情况下,都满足含头不含尾的特点
*/
str.substring(3, 5);
/*
4、得到传入字符串在原串中首次/最后一次出现的位置
int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引。
int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。
int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引。
int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。
注意:如果从头到尾都匹配不成功,则返回-1
*/
str.indexOf("学");
str.lastIndexOf("学");
str.indexOf("学", 5);
/*
5、将字符串转换为全大写/小写返回
String toLowerCase():使用默认语言环境的规则将此 String 中的所有字符都转换为小写。
String toUpperCase():使用默认语言环境的规则将此 String 中的所有字符都转换为大写。
*/
str.toUpperCase();
str.toLowerCase();
/*
6、去除字符串首尾的空白
String trim():返回字符串的副本,忽略前导空白和尾部空白。
*/
str.trim();
/*
7、判断字符串是否以传入的字符串开头/结尾
boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始。
boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束。
*/
str.startsWith("java");
str.endsWith("web");
/*
判断原串中是否包含传入的字符串内容
boolean contains(CharSequence s):当且仅当此字符串包含指定的 char 值序列时,返回 true。
*/
str.contains("java");
3、关于字符串的总结
1)、关于字符串的总结1:
String s1 = "hello"; //产生1个对象 在常量池中
String s2 = "hello"; //不会产生新对象
String s3 = new String("hello"); //产生1个对象 在堆中
String s4 = new String("helloworld"); //产生2个对象 一个在常量池,另一个在堆
String s5 = "helloworld";
注意事项:其它的不多说,第四行代码的意思是new一个String,会在堆里new一个对象出来,然后马上去常量池里面去看看有没有对应的字符串,如果没有,则在常量池创建一个字符串,然后堆里的这个对象指向常量池里的那个字符串,然后等号左边的String变量指向堆里的那个对象。
2)、关于字符串总结2:
String s1 = "hello"; //s1变量记录了"hello"在常量池中的地址
String s2 = "world"; //s2变量记录了"world"在常量池中的地址
String s3 = "helloworld"; //s3变量记录了"helloworld"在常量池中的地址
System.out.println(s1 + "world" == s3); // 堆 == 常量池 false
System.out.println("hello" + s2 == s3); // 堆 == 常量池 false
System.out.println(s1 + s2 == s3); // 堆 == 常量池 false
System.out.println("hello" + "world" == s3); //常量池 == 常量池 true
System.out.println("*******************************************************");
System.out.println(s1 + "world" == s1 + "world"); // 堆 == 堆 false
System.out.println("hello" + s2 == "hello" + s2); // 堆 == 堆 false
System.out.println(s1 + s2 == s1 + s2); // 堆 == 堆 false
System.out.println("hello" + "world" == "hello" + "world"); //常量池 == 常量池 true
System.out.println("*******************************************************");
/*
String intern():返回字符串对象的规范化表示形式。
解析方法:
jvm会去常量池中查找是否以前存在了该字符串常量数据对象:
如果存在,就直接返回该字符串常量数据对象在常量池中的地址;
如果不存在,则先在常量池中创建该字符串常量对象,再将地址返回;
*/
System.out.println((s1 + "world").intern() == s3); // 常量池 == 常量池 true
System.out.println(("hello" + s2).intern() == s3); // 常量池 == 常量池 true
System.out.println((s1 + s2).intern() == s3); // 常量池 == 常量池 true
System.out.println(("hello" + "world").intern() == s3); // 常量池 == 常量池 strue
本电子书目录:《Java基础的重点知识点全集》