Java字符串知识点总结

1、String的创建

1.1、普通创建方式和new关键字创建的区别

String最常用的创建方式就是:

String a = "abcd";

使用这种方式创建字符串时,jvm首先会在字符串常量池中检查是存在该字符串,如果有则将该对象的地址赋给它的引用a;若不存在则jvm会在常量池中创建这个字符串对象并将地址赋给a。还有一点需要明确:字符串一经过创建就不会改变。在这个基础上加入:

a = "xxx";

虽然a被指向了xxx,但是原来的abcd却没有变,只是jvm又在常量池中创建了新的xxx,然后让a指向xxx的地址,其示意图如下:
在这里插入图片描述
如果使用new关键字创建字符串,jvm首先检查字符串常量池,如果该字符串已经存在常量池中,那么不再在字符串常量池创建该字符串对象,而直接堆中复制该对象的副本,然后将堆中对象的地址赋值给引用s,如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中,然后在堆中复制该对象的副本,然后将堆中对象的地址赋值给引用s。

  1. String s1= “xxx”;
  2. String s2 = new String(“xxx”);

这两种创建方式的示意图如下:
在这里插入图片描述
有了以上的概念,我们来看看以下几个输出结果:

String s1 = "aaa";
String s2 = "aaa";
System.out.println(s1 == s2);  //输出结果为true
String s3 = new String("aaa");
System.out.println(s3 == s1);  //输出结果为false
String s4 = new String("aaa");
System.out.println(s3 == s4);  //输出结果为false

上述结果是很容易理解的,因为字符串常量池中已经有了aaa就不会再次创建(这说明了常量池中不会有两个相同的字符串),所以s2这个引用指向的就是之前创建的aaa,因而s1和s2指向的地址是相同的故输出结果为真;而s3指向的是堆内存中的字符串aaa(虽然也是从常量池中复制过来的,但是地址却变了)所以输出false;使用new关键字一定会在堆内存中创建对象,所以虽然s3和s4内容是一样的,但是由于它们都是new出来的所以是两个对象故地址不同,因而输出的是false。其示意图如下:

在这里插入图片描述
此外,再提一个插曲:

String s1 = "aaa";
String s2 = new String("aaa");
System.out.println(s1.equals(s2));  //输出结果为true

虽然s1和s2的地址不相同,但是String类重写了Object的equals方法,它里面比较的是字符串的内容是否相同,所以输出结果为true。

1.2、String的其他常用构造方法

(1)String():创建一个空的字符串序列,值得注意的是,String s = new String()并不等同于String s = null

(2)String(byte[] bytes):将指定的bytes数组解码成一个字符串

(3)String(char[] value):由给定的char数组创建一个字符串

(4)String(char[] value, int offset, int count):截取给定的char数组的一部分(从offset角标开始,长度为count)生成字符串

2、String的其他常用功能

2.1、获取

(1)获取字符串中字符的个数(长度)

	int length() 

(2)根据指定位置获取字符

	 char charAt(int index) 

(3)获取字符或字符串在调用者字符串中出现的位置(若没搜到返回-1,可根据这一点判断字符串中有无指定字符或字串)

    正向搜索
	int indexOf(int ch)  //返回指定字符在此字符串中第一次出现处的索引
	
	int indexOf(int ch, int fromIndex) //返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索
	
	int indexOf(String str)  //返回指定子字符串在此字符串中第一次出现处的索引

	int indexOf(String str, int fromIndex)  //返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
	 
    反向搜索
	int lastIndexOf(int ch)  //返回指定字符在此字符串中最后一次出现处的索引
	
	int lastIndexOf(int ch, int fromIndex) //返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索
	
	int lastIndexOf(String str)  //返回指定子字符串在此字符串中最右边出现处的索引 

	int lastIndexOf(String str, int fromIndex)  //返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索

(4)获取字符串中的一部分字符串(子串)

    String substring(int beginIndex) 

	String substring(int beginIndex, int endIndex) //包含开始,不包含结尾

2.2、转换

    String[] split(String regex)  //根据给定正则表达式的匹配拆分此字符串(切割)。 

    char[] toCharArray() //将此字符串转换为一个新的字符数组。 

	byte[] getBytes(Charset charset) //字符串转换成字节数组
	
	String toUpperCase() //将字符串字母大写。 

	String toLowerCase(Locale locale) //字符串字母小写

    String replace(char oldChar, char newChar)  //替换字符

	String trim() //去掉字符串两端的空格

	static String valueOf(char/boolean/char[]/double/float/long/int/Object ) //将参数转化成字符串

2.3、判断

	boolean equals(Object anObject) //比较内容是否相等

	boolean equalsIgnoreCase(String anotherString) //比较内容是否相等,不考虑大小写

	boolean startsWith(String prefix)  //判断此字符串是否以指定的前缀开始 

	boolean endsWith(String suffix) //判断此字符串是否以指定的后缀结束

2.3、比较

	int compareTo(String anotherString) //按字典顺序比较两个字符串 ,如果按字典顺序此 String 对象位于参数字符串之前,则比较结果为一个负整数。
	//如果按字典顺序此 String 对象位于参数字符串之后,则比较结果为一个正整数。如果这两个字符串相等,则结果为 0

	int compareToIgnoreCase(String str) //按字典顺序比较两个字符串,不考虑大小写。 

3、可变字符串

由于String创建的字符串是不可变的,如果改变字符串的话,jvm会在内存中创建一个新的字符串,如果经常进行修改就会浪费大量的资源。Java提供了可变字符串StringBuilder和StringBuffer来解决这个问题,它是一个类似于String的字符串缓冲区,其实体容量会随着存放字符串的增加而自动增大。

它的3种常用构造方法如下:

	StringBuffer() //构造一个其中不带字符的字符串缓冲区,初始容量为 16 个字符

	StringBuffer(int capacity)  //构造一个不带字符,但具有指定初始容量的字符串缓冲区

	StringBuffer(String str)  //构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容

常用方法:

 	StringBuffer append(boolean/char/char[]/double/float/int/long/Object/String ……) //追加字符串序列

	void setCharAt(int index, char ch) //修改指定索引处的字符

	StringBuffer reverse()  //字符串反序

	StringBuffer delete(int start, int end)  //删除字串,包括开始不包括结尾

	StringBuffer replace(int start, int end, String str)  //替换字串,包括开始不包括结尾

StringBuilder和StringBuffer有相同的API,即用法和StringBuffer相同。

String、StringBuilder和StringBuffer使用场景如下:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44965650/article/details/107149324