Java笔记17
String类
-
字符串是常量(final),创建之后不可改变(不可变性)。
-
字符串字面值存储在字符串常量池中,可以共享。
-
字符串常量池中是不会存储相同内容的字符串的。
字符串常量池在JVM数据区的演进
- JDK1.6:
此时运行时常量池包含字符串常量池
- JDK1.7:
此时运行时常量池不再包含字符串常量池
- JDK1.8:
元空间作为JVM方法区的实现,并使用本地内存
不可变性&可以共享
- 首先,我们初始化一个
String
类型的对象name
,并设置初始值为"hello"
:
package com.clown.classes.others;
public class StringDemo01 {
public static void main(String[] args) {
String name = "hello"; //1. "hello"常量储存在字符串常量池中
}
}
此过程可以用下图表示:
- 接着,我们给对象
name
赋值"zhangsan"
:
package com.clown.classes.others;
public class StringDemo01 {
public static void main(String[] args) {
String name = "hello"; //1. "hello"常量储存在字符串常量池中
name = "zhangsan"; //2. 把 "zhangsan"赋值给 name变量,给字符串赋值时,并没有修改数据,而是重新开辟一个空间 不可变性
}
}
此过程可以用下图表示:
- 再初始化一个
String
类型的对象name2
,并给它赋值"zhangsan"
:
package com.clown.classes.others;
public class StringDemo01 {
public static void main(String[] args) {
String name = "hello"; //1. "hello"常量储存在字符串常量池中
name = "zhangsan"; //2. 把 "zhangsan"赋值给 name变量,给字符串赋值时,并没有修改数据,而是重新开辟一个空间 不可变性
String name2 = "zhangsan"; //3. 初始化一个对象 name2,设置初始值为 "zhangsan",它与对象 name共享一个字符串 "zhangsan" 可以共享
}
}
此过程可以用下图表示:
使用new关键字创建String类型对象时的内存分析
- 使用
new
关键字创建一个String
类型的对象str
,并赋值"test"
package com.clown.classes.others;
public class StringDemo01 {
public static void main(String[] args) {
/*
String name = "hello"; //1. "hello"常量储存在字符串常量池中
name = "zhangsan"; //2. 把 "zhangsan"赋值给 name变量,给字符串赋值时,并没有修改数据,而是重新开辟一个空间
String name2 = "zhangsan"; //3. 初始化一个对象 name2,设置初始值为 "zhangsan",它与对象 name共享一个字符串 "zhangsan"
*/
//演示字符串的另一种创建方式:new String();
String str = new String("test"); //产生两个对象,堆、池各储存一个
}
}
此过程可以用下图表示:
使用new
关键字创建String
类型的对象,会创建一个对象test
,这个对象存储在堆中,此外,还会创建一个字符串对象"test"
,储存在字符串常量池中。但是在Java中根本就不存在两个完全一模一样的字符串对象。故堆中的test
其实是引用字符串常量池中字符串"test"
。
- 我们再使用
new
关键字创建一个String
类型的对象str2
,并赋值"test"
,比较它和对象str
的地址值
package com.clown.classes.others;
public class StringDemo01 {
public static void main(String[] args) {
/*
String name = "hello"; //1. "hello"常量储存在字符串常量池中
name = "zhangsan"; //2. 把 "zhangsan"赋值给 name变量,给字符串赋值时,并没有修改数据,而是重新开辟一个空间
String name2 = "zhangsan"; //3. 初始化一个对象 name2,设置初始值为 "zhangsan",它与对象 name共享一个字符串 "zhangsan"
*/
//演示字符串的另一种创建方式:new String();
String str = new String("test"); //产生两个对象,堆、池各储存一个
String str2 = new String("test");
System.out.println(str == str2); //false
}
}
运行结果:
其原因可以用下图解释:
String常用方法
String
类有以下常用方法:
//String常用方法
//1. length(); 返回字符串的长度
//2. charAt(); 返回下标位置的字符
//3. contains(); 判断是否包含某个子字符串
//4. toCharArray(); 返回字符串对应的数组
//5. indexOf(); 返回子字符串首次出现的位置下标
//6. lastIndexOf(); 返回子字符串最后一次出现的位置下标
//7. trim(); 去掉字符串前后的空格
//8. toUpperCase(); 把小写转成大写 //toLowerCase(); 把大写转成小写
//9. endWith(String str); 判断字符串是否以str结尾 //startWith(String str); 判断字符串是否以str开头
//10. replace(char oldChar, char newChar) / replace(String oldStr, String newStr); 用新的字符或字符串替代旧的字符或字符串
//11. split(String str); 用str对字符串进行拆分
//12. subString(); 从此字符串中截取出一都分子字符串
length()
&charAt()
&contains()
package com.clown.classes.others;
//String常用方法
//1. length(); 返回字符串的长度
//2. charAt(); 返回下标位置的字符
//3. contains(); 判断是否包含某个子字符串
public class StringDemo02 {
public static void main(String[] args) {
String content = ("java是世界上最好的编程语言");
//length(); 返回字符串的长度 不论是中英文字符还是特殊符号或空格,都是一个字符算一个长度
System.out.println(content.length()); //15
//2. charAt(); 返回下标位置的字符 同数组
System.out.println(content.charAt(0)); //j
System.out.println(content.charAt(content.length()-1)); //言
//3. contains(); 判断是否包含某个子字符串
System.out.println(content.contains("java")); //true
System.out.println(content.contains("php")); //false
}
}
运行结果:
toCharArray()
&indexOf()
&lastIndexOf()
package com.clown.classes.others;
import java.util.Arrays;
//String常用方法
//4. toCharArray(); 返回字符串对应的数组
//5. indexOf(); 返回子字符串首次出现的位置下标
//6. lastIndexOf(); 返回子字符串最后一次出现的位置下标
public class StringDemo02 {
public static void main(String[] args) {
String content = ("java是世界上最好的编程语言,java真香,都来学java");
//4. toCharArray(); 返回字符串对应的数组
System.out.println(Arrays.toString(content.toCharArray()));
//5. indexOf(); 返回子字符串首次出现的位置下标
System.out.println(content.indexOf("java")); //0 返回的是首次出现的位置下标
//indexOf(String str, int fromIndex); 用于从给定的fromIndex获取字符串中指定字符的索引。 这意味着搜索字符将从给定索引(fromIndex)开始
System.out.println(content.indexOf("java",4)); //16 返回的是从content.charAt(4)开始,"java"首次出现的位置下标
//6. lastIndexOf(); 返回子字符串最后一次出现的位置下标
System.out.println(content.lastIndexOf("java")); //26
}
}
运行结果:
trim()
&toUpperCase()
/toLowerCase()
&endWith()
/startWith()
package com.clown.classes.others;
//String常用方法
//7. trim(); 去掉字符串前后的空格
//8. toUpperCase(); 把小写转成大写 //toLowerCase(); 把大写转成小写
//9. endWith(String str); 判断字符串是否以str结尾 //startWith(String str); 判断字符串是否以str开头
public class StringDemo02 {
public static void main(String[] args) {
String content2 = " Hello World ";
String filename = "hello.java";
//7. trim(); 去掉字符串前后的空格
System.out.println(content2.trim()); //"Hello World"
//8. toUppercase(); 把小写转成大写
System.out.println(content2.toUpperCase()); //" HELLO WORLD "
//toLowerCase(); 把大写转成小写
System.out.println(content2.toLowerCase()); //" hello world "
//9. endWith(String str); 判断字符串是否以str结尾
System.out.println(filename.endsWith(".java")); //true
//startWith(String str); 判断字符串是否以str开头
System.out.println(filename.startsWith("hello")); //true
}
}
运行结果:
replace()
&split()
&subString()
package com.clown.classes.others;
//String常用方法
//10. replace(char oldChar, char newChar) / replace(String oldStr, String newStr); 用新的字符或字符串替代旧的字符或字符串
//11. split(String str); 用str对字符串进行拆分
//12. subString(); 从此字符串中截取出一都分子字符串
public class StringDemo02 {
public static void main(String[] args) {
String content = ("java是世界上最好的编程语言,java真香,都来学java");
String say = ("java is the best programming language,Learn it !");
//10. replace(char oldChar, char newChar) / replace(String oldStr, String newStr); 用新的字符或字符串替代旧的字符或字符串
System.out.println(content.replace("java","php")); //php是世界上最好的编程语言,php真香,都来学php
//11. split(String str); 用str对字符串进行拆分
String[] strings1 = say.split(" "); //用一个空格对字符串进行拆分
String[] strings2 = say.split("[ ,]"); //用一个空格" "或者一个逗号","对字符串进行拆分
String[] strings3 = say.split("[ ,]+"); //用一个(或多个)空格" "或者一个(或多个)逗号","对字符串进行拆分
//打印strings1
for (String str : strings1){ //增强for循环 遍历
System.out.print("["+str+"]"+"\t"); //[java] [is] [the] [] [] [] [best] [programming] [language,Learn] [it] [!]
}
System.out.println(); //换行
//打印strings2
for (String str : strings2){ //增强for循环 遍历
System.out.print("["+str+"]"+"\t"); //[java] [is] [the] [] [] [] [best] [programming] [language] [Learn] [it] [!]
}
System.out.println(); //换行
//打印strings3
for (String str : strings3){ //增强for循环 遍历
System.out.print("["+str+"]"+"\t"); //[java] [is] [the] [best] [programming] [language] [Learn] [it] [!]
}
System.out.println(); //换行
//12. subString(); 从此字符串中截取出一都分子字符串
//subString(int beginIndex) 单个参数:从参数的下标开始取,返回一段子字符串
System.out.println(content.substring(4)); //是世界上最好的编程语言,java真香,都来学java
//subString(int beginIndex, int endIndex) 截取从beginIndex到endIndex的子字符串 [begin,end)
System.out.println(content.substring(16,22)); //java真香
}
}
运行结果:
- 练习:
package com.clown.classes.others;
/*
已知 String str = "this is a text";
1. 将str中的单词单独获取出来
2. 将str中的 text替换为 practice
3. 在text前面插入一个 easy
4. 将每个单词的首字母改为大写
*/
public class StringDemo03 {
public static void main(String[] args) {
String str = "this is a text";
System.out.println("=============== 1.将str中的单词单独获取出来 ===============");
String[] s1 = str.split(" ");
for (String string1 : s1){
System.out.println(string1);
}
System.out.println("============= 2.将str中的text替换为practice =============");
System.out.println(str.replace("text","practice"));
System.out.println("=============== 3.在text前面插入一个 easy ===============");
System.out.println(str.replace("text","easy text"));
System.out.println("=============== 4.将每个单词的首字母改为大写 ==============");
String[] s2 = str.split(" ");
//方法一:使用replace()方法
for (int i=0; i<s2.length; i++){
char first = s2[i].charAt(0); //获取每个单词的首字母
char upperfirst = Character.toUpperCase(first); //将每个单词的首字母转为大写
if (i == s2.length-1){ //判断是否是最后一个单词
System.out.println(s2[i].replace(first,upperfirst)); //是,结尾不加空格
}else {
System.out.print(s2[i].replace(first,upperfirst)+" "); //不是,结尾加上一个空格
}
}
//方法二:使用substring()方法
for (int i=0; i<s2.length; i++){
char first = s2[i].charAt(0); //获取每个单词的首字母
char upperfirst = Character.toUpperCase(first); //将每个单词的首字母转为大写
String newstr = upperfirst+s2[i].substring(1);
if(i == s2.length-1){ //判断是否是最后一个单词
System.out.println(newstr); //是,结尾不加空格
}else {
System.out.print(newstr+" "); //不是,结尾加上一个空格
}
}
}
}
运行结果: