常用类(3):String类
一、String类概述
1、String类的特点介绍
观察API发现:
1、String代表的是字符串,属于java.lang下面的,所以使用的时候不需要导包
2、String类代表字符串
Java程序中的所有字符串文字(例如"abc" )都被实现为此类的实例(实例代表的是对象)
3、字符串不变; 它们的值在创建后不能被更改
(意思是字符串是常量,一旦被赋值,就不能改变)
2、字符串含义
就是由多个字符组成的数据,叫做字符串;也可以看作是一个字符数组
二、String类的构造方法
(1)public String()
//重写了Object类中的toString方法
(2)public String(byte[] bytes)
//将字节数组转成一个字符串
(3)public String(byte[] bytes,int offset,int length)
//将字节数组中的一部分截取出来变成一个字符串
(4)public String(char[] value)
//将字符数组转成一个字符串
(5)public String(char[] value,int offset,int count)
//将字符数组中的一部分截取出来变成一个字符串
(6)public String(String original)
(1)public String()
public class StringDemo {
public static void main(String[] args) {
//使用构造方法创建对象
String s = new String();
System.out.println(s);
}
}
//打印的结果是空的(什么也没有),说明重写了Object类中的toString方法
查看字符串的长度: 对象名.length()
public class StringDemo {
public static void main(String[] args) {
//使用构造方法创建对象
String s = new String();
//查看字符串的长度
//API:public int length()返回此字符串的长度
System.out.println("字符串的长度为:"+s.length());
}
}
执行结果如下:
字符串的长度为:0
Process finished with exit code 0
(2) public String(byte[] bytes)
public String(byte[] bytes)
意思是:构造方法String需要传入一个字节数组,将这个字节数组转成一个字符串
public class StringDemo {
public static void main(String[] args) {
//public String(byte[] bytes) 将一个字节数组转成一个字符串
//首先创建一个byte类型的数组
byte[] b = {97,98,99,100,};
//将b传入对象中
String s = new String(b);
System.out.println("数组转换成字符串为:"+s);
System.out.println("字符串的长度为:"+s.length());
}
}
执行结果如下:
数组转换成字符串为:abcd
字符串的长度为:4
Process finished with exit code 0
(3)public String(byte[] bytes,int offset,int length)
public String(byte[] bytes,int offset,int length)
意思是:构造方法String传入一个字节数组,将这个字节数组中的一部分截取出来变成一个字符串
(offset理解为:下标、索引)
public class StringDemo {
public static void main(String[] args) {
//首先创建一个byte类型的数组
byte[] b = {97,98,99,100,101,102};
String s = new String(b);
System.out.println("转换为的字符串:"+s);//abcdef
//创建对象,将b传入进去
String s1 = new String(b,1,3);//从下标(索引)为1开始截,截3个
System.out.println("截取后的字符串为:"+s1);
}
}
执行结果如下:
转换为的字符串:abcdef
截取后的字符串为:bcd
Process finished with exit code 0
//截取的时候注意不要超出边界
(4)public String(char[] value)
public String(char[] value)
构造方法String需要传入一个字符数组,将这个字符数组转成一个字符串
public class StringDemo {
public static void main(String[] args) {
//创建一个字符数组
char[] c = {'a','b','c','d','我','爱','阿','伟'};
//创建对象,将数组c传入进去
String s = new String(c);
System.out.println("字符转换为字符串为:"+s);
}
}
执行结果如下:
字符转换为字符串为:abcd我爱阿伟
Process finished with exit code 0
(5)public String(char[] value,int offset,int count)
public String(char[] value,int offset,int count)
构造方法String传入一个字符数组,将这个字符数组中的一部分截取出来变成一个字符串
public class StringDemo {
public static void main(String[] args) {
//创建一个字符数组
char[] c = {'a','b','c','d','我','爱','阿','伟'};
//创建对象,将数组c传入进去
String s = new String(c);
System.out.println("字符转换为字符串为:"+s);
String s1 = new String(c, 4, 4);//从索引为4开始截,截4个
System.out.println("截取后的字符串为:"+s1);
}
}
执行结果如下:
字符转换为字符串为:abcd我爱阿伟
截取后的字符串为:我爱阿伟
Process finished with exit code 0
(6)public String(String original)
/*
1、方法区中有一个常量池区域,Java虚拟机现在常量池中找“你好”,如果有将“你好”地址值赋给s;
如果没有,在常量池里开辟一个空间,空间里有“你好”,地址值假设为0x001,然后将0x001赋给s
然后String s这个空间指向“你好”这个常量池
2、String s1 = new String(s);表示在栈里面开辟一个区域叫String s1
new String(s)表示将在堆里面开辟一个区域叫new String(s),假设地址值为0x0001;
new String(s)这个区域里面放的是“你好”字符串的地址值0x001,
然后 new String(s)这个区域指向“你好”常量池,
new String(s)这个区域的地址值赋给s1,s1指向这个区域
3、自始至终,内存里就一个“你好”字符串
以上分析为说明API里的一句话:
初始化新创建的String对象,使其表示与参数相同的字符序列; 换句话说,新创建的字符串是参数字符串的副本。
除非需要original的显式副本, original使用此构造函数是不必要的,因为Strings是不可变的
*/
案例:
/*
字符串是常量,它的值在创建之后不能更改
String s = “hello”;
s += “world”;
问s的结果是多少?
*/
public class StringDemo2 {
public static void main(String[] args) {
String s = "hello";
s += "world";
System.out.println(s);
}
}
执行结果如下:
helloworld
Process finished with exit code 0
为Strings是不可变的,那为什么程序没报错,反而执行出来了?
1、Java虚拟机在常量池中没有找到“hello”,那么会开辟一个空间,"hello"放进去,假设地址值为0x01,
将0x01赋给s;s通过地址值0x01指向“hello”
2、Java虚拟机在常量池中没有找到“world”,那么也会开辟一个空间,“world”放进去,假设地址值为0x02
然后拿着“hello”进行拼接,得到一个新的字符串“helloworld”,假设“helloworld”地址值为0x02,
将0x02赋给s,s指向“helloworld”
特点:字符串一旦被创建,它的值就不能被改变,指的是字符串在常量池中的值不能改变
4、String类的面试题
/*
String s = new String(“hello”)和String s = “hello”;的区别?
字符串比较之看程序写结果
字符串拼接之看程序写结果
*/
public class StringDemo3 {
public static void main(String[] args) {
//创建对象,将hello传入进去
String s1 = new String("hello");
String s2 = "hello";
System.out.println(s1==s2);
System.out.println(s1.equals(s2)); //true
}
}
执行结果如下:
false
true
Process finished with exit code 0
结果分析:
1、==比较引用数据类型的时候,比较的是地址值
String s1 = new String("hello");在堆内存中创建对象
String s1指向堆,String s2指向常量池
所以二者结果不一样,即false
2、String类中重写了Object的equals方法,equals方法默认比较的是地址值,但是由于重写 了,所以s1与s2比较的是内容hello,即true
5、例题
public class StringDemo5 {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "world";
String s3 = "helloworld";
String s4 = "hello"+"world";
System.out.println(s3==s4); //true
System.out.println(s3==s1+s2); //false
System.out.println(s3.equals(s1+s2)); //true
执行结果为:
true
false
true
Process finished with exit code 0
结果分析:
字符串如果是常量相加,是先相加,然后去常量池中找,如果找到了,就返回,如果找不到就创建;
字符串如果是变量相加,是先开辟空间,然后再拼接,拼接后获得了一个全新的地址值
s4是"hello"、"world"两个常量相加,s3==s1+s2表示s3是两个变量相加
即s3==s4是true,s3==s1+s2是false
如果想明确获取地址值,可以使用API工具类中System类中的identityHashCode()方法来获取
public class StringDemo5 {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "world";
String s3 = "helloworld";
String s4 = "hello"+"world";
String s5 = s1+s2;
System.out.println(System.identityHashCode(s1));//356573597
System.out.println(System.identityHashCode(s2));//1735600054
System.out.println(System.identityHashCode(s3));//21685669
System.out.println(System.identityHashCode(s4));//21685669
System.out.println(System.identityHashCode(s5));//2133927002
}
}
三、String类的判断功能
(1)boolean equals(Object obj)
//比较字符串的内容是否相同 区分大小写
(2)boolean equalsIgnoreCase(String str)
//比较字符串的内容是否相同,忽略大小写
(3)boolean contains(String str)
//判断大的字符串中是否包含小的字符串,如果包含,返回true,反之false,区分大小写
(4)boolean startsWith(String str)
//测试此字符串是否以指定的前缀开头,区分大小写
(5)boolean endsWith(String str)
//测试此字符串是否以指定的后缀结束,区分大小写
(6)boolean isEmpty()
//判断字符串是否是空字符串
(1)boolean equals(Object obj):比较字符串的内容是否相同 区分大小写
public class StringDemo6 {
public static void main(String[] args) {
String s1 = "helloworld";
String s2 = "Helloworld";
String s3 = "HelloWorld";
String s4 = "";
String s5 = null;//null没有地址值
System.out.println(s1.equals(s2));//false
System.out.println(s1.equals(s3));//false
System.out.println(s4.equals(s5));//false
}
}
(2)boolean equalsIgnoreCase(String str):比较字符串的内容是否相同,忽略大小写
public class StringDemo6 {
public static void main(String[] args) {
String s1 = "helloworld";
String s2 = "Helloworld";
String s3 = "HelloWorld";
System.out.println(s1.equalsIgnoreCase(s2));//true
System.out.println(s1.equalsIgnoreCase(s3));//true
}
}
(3)boolean contains(String str):
判断大的字符串中是否包含小的字符串,如果包含,返回true,反之false,区分大小写
public class StringDemo6 {
public static void main(String[] args) {
String s1 = "helloworld";
String s2 = "Helloworld";
String s3 = "HelloWorld";
//当且仅当此字符串包含指定的char值序列时才返回true。
//判断大的字符串中是否包含小的字符串,如果包含,返回true,反之false,区分大小写
System.out.println(s1.contains("Hello"));//false
System.out.println(s1.contains("leo"));//false
System.out.println(s1.contains("hello"));//true
}
}
(4)boolean startsWith(String str):测试此字符串是否以指定的前缀开头,区分大小写
public class StringDemo6 {
public static void main(String[] args) {
String s1 = "helloworld";
String s2 = "Helloworld";
String s3 = "HelloWorld";
//测试此字符串是否以指定的前缀开头,区分大小写
System.out.println(s1.startsWith("hel"));//true
System.out.println(s1.startsWith("h"));//true
System.out.println(s1.startsWith("he"));//true
System.out.println(s1.startsWith("he34"));//false
System.out.println(s1.startsWith("H"));//false
}
}
(5)boolean endsWith(String str):测试此字符串是否以指定的后缀结束,区分大小写
public class StringDemo6 {
public static void main(String[] args) {
String s1 = "helloworld";
String s2 = "Helloworld";
String s3 = "HelloWorld";
//测试此字符串是否以指定的后缀结束,区分大小写
System.out.println(s1.endsWith("orld"));//true
System.out.println(s1.endsWith("orlD"));//false
}
}
(6)boolean isEmpty():判断字符串是否是空字符串
public class StringDemo6 {
public static void main(String[] args) {
String s1 = "helloworld";
String s2 = "Helloworld";
String s3 = "HelloWorld";
String s4 = "";
String s5 = null;
String s6 = "bigdata";
String s7 = null;
//boolean isEmpty() 判断字符串是否是空字符串
System.out.println(s1.isEmpty());//false
System.out.println(s4.isEmpty());//true
System.out.println(s6.equals(s7));//false
//null不能调方法,会报错
//System.out.println(s5.isEmpty());
//System.out.println(s7.equals(s6));
}
}
注意:
字符串之间比较的要求,在不知道两个字符串变量的值的时候,为了防止空指针异常,把变量放在后面
案例:
//需求:将s6,s7与"hadoop"进行比较
System.out.println("hadoop".equals(s6));
System.out.println("hadoop".equals(s7));
四、String类的获取功能
(1)int length()
//获取字符串的长度
(2)char charAt(int index)
//返回char字符指定位置索引的值,索引从0开始到length()-1
(3)int indexOf(int ch)
//返回指定字符第一次出现的字符串内的索引,如果此字符串中没有此类字符,则返回-1
(4)int indexOf(String str)
//返回的是字符串中第一个字符在大字符串中的索引值,如果值不存在,则返回-1
(5)int indexOf(int ch,int fromIndex)
//返回指定字符第一次出现在字符串中的索引,以指定的索引开始搜索,如果值不存在,则返回-1
(6)int indexOf(String str,int fromIndex)
//返回字符串中第一个字符在大字符串中的索引值,以指定的索引开始搜索,如果值不存在,则返回-1
(7)String substring(int start)
//子字符串从指定的索引处开始,并扩展到字符串的末尾,包含开始索引位置的
(8)String substring(int start,int end)
//字串开始于start位置,并截取到end-1的位置,左闭右开(含头不含尾)
(1)int length():获取字符串的长度
public class StringDemo7 {
public static void main(String[] args) {
String s = "helloworld";
//int length() 获取字符串的长度
System.out.println(s.length());//10
}
}
(2)char charAt(int index):返回char字符指定位置索引的值,索引从0开始到length()-1
public class StringDemo7 {
public static void main(String[] args) {
String s = "helloworld";
//char charAt(int index) 返回char字符指定位置索引的值,索引从0开始到length()-1
System.out.println(s.charAt(7));//r
System.out.println(s.charAt(0));//h
}
}
(3)int indexOf(int ch):返回指定字符第一次出现的字符串内的索引,如果此字符串中没有此类字符,则返回-1
public class StringDemo7 {
public static void main(String[] args) {
String s = "helloworld";
//int indexOf(int ch)
//返回指定字符第一次出现的字符串内的索引,如果此字符串中没有此类字符,则返回-1
System.out.println(s.indexOf('l'));//2
System.out.println(s.indexOf(97));//-1
}
}
(4)int indexOf(String str):返回的是字符串中第一个字符在大字符串中的索引值,如果值不存在,则返回-1
public class StringDemo7 {
public static void main(String[] args) {
String s = "helloworld";
//int indexOf(String str)
//helloworld
//返回的是字符串中第一个字符在大字符串中的索引值,如果值不存在,则返回-1
System.out.println(s.indexOf("owo"));
System.out.println(s.indexOf("qwer"));
}
}
(5)int indexOf(int ch,int fromIndex):
返回指定字符第一次出现在字符串中的索引值,以指定的索引开始搜索,如果值不存在,则返回-1
public class StringDemo7 {
public static void main(String[] args) {
String s = "helloworld";
//int indexOf(int ch,int fromIndex)
//返回指定字符第一次出现在字符串中的索引,以指定的索引开始搜索,如果值不存在,则返回-1
System.out.println(s.indexOf('l',4));//从索引4开始搜索,在索引8第一次出现字符'l'
System.out.println(s.indexOf('p',4)); //-1
System.out.println(s.indexOf('l',40));//-1
System.out.println(s.indexOf('p',40));//-1
}
}
(6)int indexOf(String str,int fromIndex):
返回字符串中第一个字符在大字符串中的索引值,以指定的索引开始搜索,如果值不存在,则返回-1
(7)String substring(int start):
子字符串从指定的索引处开始,并扩展到字符串的末尾,,包含开始索引位置的值
public class StringDemo7 {
public static void main(String[] args) {
String s = "helloworld";
//String substring(int start)
//返回的是一个字符串,该字符串是此字符串的子字符串
//子字符串从指定的索引处开始,并扩展到字符串的末尾,包含开始索引位置的值
System.out.println(s.substring(3)); //loworld
}
}
(8)String substring(int start,int end):字串开始于start位置,并截取到end-1的位置,左闭右开(含头不含尾)
public class StringDemo7 {
public static void main(String[] args) {
String s = "helloworld";
//String substring(int start,int end)
//返回的是一个字符串,该字符串是此字符串的子字符串
//字串开始于start位置,并截取到end-1的位置,左闭右开(含头不含尾)
System.out.println(s.substring(5,10));//world
}
}
五、String类的转换功能
字符串的转换功能:
(1)byte[] getBytes()
//使用平台的默认字符集将此String编码为字节序列,将结果存储到新的字节数组中
(2)char[] toCharArray()
//将字符串转换成字符数组
(3)static String valueOf(char[] chs)
//将字符数组转换成字符串(需要传入参数)
(4)static String valueOf(int i)
//将int类型的数据转换成字符串类型(需要传入参数)
(5)String toLowerCase()
//将字符串中的内容全部转换成小写
(6)String toUpperCase()
//将字符串中的内容全部转换成大写
(7)String concat(String str)
//将小括号中的字符串拼接到大字符串的后面(需要传入参数)
(1)byte[] getBytes():使用平台的默认字符集将此String编码为字节序列,将结果存储到新的字节数组中
public class StringDemo {
public static void main(String[] args) {
String s = "HelloWorLD";
//byte[] getBytes()
//使用平台的默认字符集将此String编码为字节序列,将结果存储到新的字节数组中
byte[] b = s.getBytes();//s.getBytes().var回车
//数组需要遍历,如果直接输出,将会是一个地址值
//System.out.println(b1); //[B@4554617c
for(int i=0;i<b1.length;i++){
System.out.println(b[i]);
}
}
}
执行结果如下:
72
101
108
108
111
87
111
114
76
68
Process finished with exit code 0
(2)char[] toCharArray():将字符串转换成字符数组
public class StringDemo {
public static void main(String[] args) {
String s = "HelloWorLD";
//char[] toCharArray()
//将字符串转换成字符数组
char[] c = s.toCharArray();
//第一个方法遍历
for(int i=0;i<c1.length;i++){
System.out.printIn(c[i]);
}
/*
第二个方法遍历
增强for循环,后面集合的时候会讲解,它是用来替代迭代器的
for(char c : c1){
System.out.print(c);
}
*/
}
}
执行结果如下:
H
e
l
l
o
W
o
r
L
D
Process finished with exit code 0
(3)static String valueOf(char[] chs):将字符数组转换成字符串(需要传入参数)
public class StringDemo {
public static void main(String[] args) {
String s = "HelloWorLD";
//先将字符串转换成字符数组
char[] c = s.toCharArray();
//static String valueOf(char[] chs)
//将字符数组转换成字符串
//该方法是静态的,通过类名直接调取
String s = String.valueOf(c);
System.out.println(s);
}
}
执行结果如下:
HelloWorLD
Process finished with exit code 0
(4)static String valueOf(int i):将int类型的数据转换成字符串类型
public class StringDemo {
public static void main(String[] args) {
//static String valueOf(int i)
//将int类型的数据转换成字符串类型
String s = String.valueOf(100); //100 -->"100"
System.out.println(s2); //100
}
}
(5)String toLowerCase():将字符串中的内容全部转换成小写
public class StringDemo {
public static void main(String[] args) {
String s = "HelloWorLD";
//String toLowerCase()
//将字符串中的内容全部转换成小写
String s1 = s.toLowerCase();
System.out.println(s1); //helloworld
}
}
(6)String toUpperCase():将字符串中的内容全部转换成大写
public class StringDemo {
public static void main(String[] args) {
String s = "HelloWorLD";
//String toUpperCase()
//将字符串中的内容全部转换成大写
String s1 = s.toUpperCase();
System.out.println(s1); //HELLOWORLD
}
}
(7)String concat(String str):将小括号中的字符串拼接到大字符串的后面(需要传入参数)
public class StringDemo {
public static void main(String[] args) {
String s = "HelloWorLD";
//String concat(String str)
//将小括号中的字符串拼接到大字符串的后面(需要传入参数)
String s1 = s.concat("hadoop");
System.out.println(s1);//HelloWorLDhadoop
}
}
六、String类的其他功能(替换、去除空格、字典顺序比较)
/*
替换功能
String replace(char old,char new)//字符替换字符
String replace(String old,String new)//字符串替换字符串
去除字符串两空格
String trim()
按字典顺序比较两个字符串
int compareTo(String str)
int compareToIgnoreCase(String str)
*/
public class StringDemo11 {
public static void main(String[] args) {
String s = "helloworldowodadadwowo";
//String replace(char old,char new)
//将新的字符替换字符中指定的所有字符,并返回新的字符串
String s1 = s.replace('l', 'a');//把所有的l用a替换
System.out.println(s1);//heaaoworadowodadadwowo
//String replace(String old,String new)
//将字符串中旧的小串用新的小串替换,返回一个新的字符串
String s2 = s.replace("owo", "wow");
System.out.println(s2);//hellwowrldwowdadadwwow
String s3 = s.replace("owo", "qwerdf");
System.out.println(s3);//hellqwerdfrldqwerdfdadadwqwerdf
//如果被替换的字符串不存在,返回的是原本的字符串
String s4 = s.replace("qwer", "poiu");
System.out.println(s4);//helloworldowodadadwowo
//String trim() 去除字符串两边的空格
String s5 = " hello world ";
System.out.println(s5); // hello world
System.out.println(s5.trim()); //hello world
//int compareTo(String str)
String s6 = "hello";//首字母h的ASCII码值104
String s7 = "hello";//首字母h的ASCII码值104
String s8 = "abc"; //首字母a的ASCII码值97
String s9 = "qwe"; //首字母q的ASCII码值113
System.out.println(s6.compareTo(s7)); //0 104-104=0
System.out.println(s6.compareTo(s8)); //7 104-97=7
System.out.println(s6.compareTo(s9)); //-9 104-113=-9
//如果首字母一样,字符个数不一样,个数相减
String s10 = "hel";
System.out.println(s6.compareTo(s10)); //2 5-3=2
}
}