1、String类
- 下面我们来看一下字符串的应用场景:
- 比如,我们在上传图片的时候,针对图片的格式,我们要利用字符串来对文件的后缀(扩展名)进行比较;
- 再比如,我们在登录邮箱时,要利用字符串对用户名和密码进行验证等等。
1.1、String对象的创建
- 方式1:
String str="chaixingsi";
- 方式2:
String str2=new String();//创建了一个空字符串
或者String str3 = new String("chaixingsi");
1.2、String的常用方法
方法 | 说明 |
---|---|
int length() | 返回当前字符串的长度 |
int indexOf(int ch) | 查找ch字符在该字符串中第一次出现的位置 |
int indexOf(String str) | 查找str字符在该字符串中第一次出现的位置 |
int lastIndexOf(int ch) | 查找ch字符在该字符串中最后一次出现的位置 |
int lastIndexOf(String str) | 查找str字符在该字符串中最后一次出现的位置 |
String substring(int beginIndex) | 获取从beginIndex位置开始到结束的子字符串 |
String substring(int beginIndex,int endIndex) | 获取从beginIndex位置开始到endIndex位置结束的子字符串 |
String trim() | 返回了去除前后空格的字符串 |
boolean equals(Object obj) | 将该字符串与指定对象比较,返回true或false |
String toLowerCase() | 将字符串转换为小写 |
String toUpperCase() | 将字符串转换为大写 |
char charAt(int index) | 获取字符串中指定位置的字符 |
String[] split(String regex,int limit) | 将字符串分割为子字符串,返回字符串数组 |
byte[] getBytes() | 将该字符串转换为byte数组 |
下面进行代码演示(只对部分方法演示)。
- 1.新建一个名为
StringProj
的Java项目,新建一个com.cxs.string
的包,并新建一个StringDemoOne
的类,并勾选主方法,代码如下。
public class StringDemoOne {
public static void main(String[] args) {
String str = "Java 编程 基础";
System.out.println("字符串长度为:" + str.length());// 空格也计算在内,这里有两个空格
System.out.println(str.charAt(6));// 第7个字符,下标从0开始
System.out.println(str.substring(5));
// 第二个参数代表输出末尾字符的下一个字符的索引值
System.out.println(str.substring(5, 7));
System.out.println("---------------------------");
String str2 = new String("JAVA编程基础,我喜欢java编程");
System.out.println("字符'A'第一次出现的位置:" + str2.indexOf('A'));
System.out.println("子串\"编程\"第一次出现的位置:" + str2.indexOf("编程"));
System.out.println("字符'A'最后一次出现的位置:" + str2.lastIndexOf('A'));
System.out.println("子串\"编程\"最后一次出现的位置:" + str2.lastIndexOf("编程"));
System.out.println("从字符串index为8的位置开始,子串\"编程\"第一次出现的位置:" + str2.indexOf("编程", 8));
}
}
- 2.运行代码,结果如下。
1.3、字符串与byte数组间的相互转换
- 1.新建一个名为StringDemoTwo的类,并勾选主方法。
public class StringDemoTwo {
public static void main(String[] args) throws UnsupportedEncodingException {
String str = new String("JAVA 编程 基础");
byte[] arrs = str.getBytes();// 将字符串转换为byte数组
for (int i = 0; i < arrs.length; i++) {
System.out.print(arrs[i] + " ");
}
System.out.println("\n" + "\n" + "\n");
System.out.println("-----------------------");
String str1 = new String(arrs);// 将byte数组转换为字符串
System.out.println(str1);
}
}
- 2.运行代码结果如下。
- 3.windows下的Eclipse默认编码为GBK,在GBK编码中,一个汉子占用两个字节,如上所示。
- 4.修改代码,将其编码改为UTF-8,并做一下异常处理,此处我们只是声明抛出。
public class StringDemoTwo {
public static void main(String[] args) throws UnsupportedEncodingException {// ←--修改此处
String str = new String("JAVA 编程 基础");
byte[] arrs = str.getBytes("UTF-8");// ←--修改此处
for (int i = 0; i < arrs.length; i++) {
System.out.print(arrs[i] + " ");
}
System.out.println("\n" + "\n" + "\n");
System.out.println("-----------------------");
String str1 = new String(arrs, "UTF-8");// ←--修改此处
System.out.println(str1);
}
}
- 5.运行代码结果如下。在
UTF-8
编码中,一个汉字占用三个字节。
拓展:有关Java中一个汉字占用字节的问题详见博客:Java一个汉字占几个字节(详解与原理)
1.4、等于运算符与equals方法的区别
- 1.新建一个名为StringDemoThree的类,并勾选主方法。
public class StringDemoThree {
public static void main(String[] args) {
String str1 = "chaixingsi";
String str2 = "chaixingsi";
String str3 = new String("chaixingsi");
String str4 = new String("chaixingsi");
System.out.println("str1与str2内容相同吗?" + str1.equals(str2));
System.out.println("str1与str3内容相同吗?" + str1.equals(str3));
System.out.println("str3与str4内容相同吗?" + str3.equals(str4));
System.out.println("-----------------");
System.out.println("str1与str2地址相同吗?" + (str1 == str2));
System.out.println("str1与str3地址相同吗?" + (str1 == str3));
System.out.println("str3与str4地址相同吗?" + (str3 == str4));
}
}
- 2.运行代码结果如下。
- 3.分析:
- 如上图,栈是用来存放类的引用;
- 常量池可以存储字符串常量;
- 堆存放的是通过new关键字创建的对象。
- 执行
String str1="chaixingsi";
会在常量池当中生成字符串常量”chaixingsi”,并将该常量的引用str1存放到堆当中,并且str1引用会指向常量池中的常量; - 而在生成字符串常量str2时,此时发现常量池中已经存在该常量了,则str2的引用直接指向该字符串常量;因此str1和str2的内容和引用地址都相同;
- 执行
String str3 = new String("chaixingsi");
,详见Java面向对象,即在栈当中声明一个对象str3,通过new关键字在堆当中完成对象的实例化操作,并将该对象的地址存放到栈当中,即str3引用指向了堆当中创建的实例对象。同理,以同样的方式创建对象str4;此时str3和str4指向的是不同的内存空间,因此他们的地址是不同的,而str1和str3的地址显然也是不同的。
1.5、字符串的不可变性
- 字符串一旦被创建,则不能被修改,是不可变的。
- 若字符串被修改,则会创建一个新的对象,即字符串一旦被重新赋值,便会开辟一个新的空间,而原先的字符串对象并没有改变,它会被废弃(回收)。
- 1.新建一个名为StringDemoFour的类,并勾选主方法,代码如下。
public class StringDemoFour {
public static void main(String[] args) {
String s1 = "chaixingsi";
String s2 = "hello," + s1;//此时s1并没有发生变化
System.out.println("s1=" + s1);
System.out.println("s2=" + s2);
}
}
- 2.运行代码结果如下。
- 具体解释看下图。
- 3.修改代码如下,再次运行。
public class StringDemoFour {
public static void main(String[] args) {
String s1 = "chaixingsi";
System.out.println("s1=" + s1);
s1 = "hello," + s1;// 此时s1指向了新的字符串常量,即新的内存空间
System.out.println("s1=" + s1);
}
}
- 4.运行代码,结果如下。
- 5.具体解释如下图所示,s1指向了新的内存空间。经过重新赋值(即修改)操作,s1指向了新的字符串常量,此时不再有引用指向原先的字符串常量了(被废弃了)。
- 6.继续编写代码。
public class StringDemoFour {
public static void main(String[] args) {
String s1 = "chaixingsi";
System.out.println("s1=" + s1);
s1 = "hello," + s1;// 此时s1指向了新的字符串常量,即新的内存空间
System.out.println("s1=" + s1);
System.out.println("-----------------");
// 通过new关键字产生的对象是在堆当中实例化的
String s3 = new String("hello,chaixingsi");
// 通过substring方法生成的子串hello会被存放到常量池当中
System.out.println("子串" + s3.substring(0, 5));
System.out.println("s3=" + s3);
}
}
- 7.运行结果如下。注意:通过substring方法生成的子串会存放到常量池当中。
2、StringBuilder类
- 与
String
的不可变性相比,StringBuilder
具有可变性,当频繁地操作字符串的时候,我们就要用到StringBuilder
了。 - 由于
String
的不可变性,当频繁操作字符串时会产生很多中间变量,并且会在常量池当中产生许多废弃的数据,而使用StringBuilder
就可以避免发生这种情况。 - 提到
StringBuilder
就得提到StringBuffer
了,两者基本相似,但是StringBuffer
是线程安全的(线程安全的话速度相对慢些),而StringBuilder
则不具备,所以StringBuilder
性能也略高。 - 线程安全主要针对的是多线程,在单线程中使用
StringBuilder
即可。 下图为StringBuilder的构造方法,默认的构造方法字符容量为16个字符。
关于StringBuilder的其他常用方法,请自行查阅官方的API文档。
1.新建一个名为
StringBuilderDemo
的类,并勾选主方法。
public class StringBuilderDemo {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("hello");
builder.append(",").append("chaixingsi").append("!");
System.out.println("builder=" + builder);
System.out.println("--------------------------");
// 仅将名字改为大写
// builder.delete(6, 16).insert(6, "CHAIXINGSI");//方式1
builder.replace(6, 16, "CHAIXINGSI");// 方式2
System.out.println("修改后builder=" + builder);
System.out.println("--------------------------");
System.out.println("取子串hello结果:" + builder.substring(0, 5));
}
}
- 2.运行代码结果如下。