字符串相关类

版权声明:原创内容是本人学习总结,仅限学习使用,禁止用于其他用途。如有错误和不足,欢迎评论指正补充。 https://blog.csdn.net/qian_qian_123/article/details/82354424

2. 字符串相关类

2.1 String的特点

2.1.1 字符串的实例化

字符串的两种实例化方式及其差别

​ 1).String str = “abc”;

​ 2).String str = new String(“abc”);

​ Java运行时会维护一个String Pool(String池), 也叫“字符串缓冲区”。String池用来存放运行时中产生的各种字符串,并且池中的字符串的内容不重复。而一般对象不存在这个缓冲池,并且创建的对象仅仅存在于方法的堆栈区。

​ 当用户采用直接赋值实例化String对象的时候,如果是第一次定义,则会自动的将对象的内容(字符串内容)保存在字符串对象池之中,以后如果其他的字符串对象依然采用直接赋值的话,可以直接通过对象池取出已经保存的内容继续使用,而不会再重新开辟新的空间

​ String对象的创建很讲究需要注意的点如下:

​ a.当使用任何方式来创建一个字符串对象s时,Java运行时(运行中JVM)会拿着这个s在String池中找是否存在内容相同的字符串对象,如果不存在,则在池中创建一个字符串s,否则,不在池中添加

​  b.Java中,只要使用new关键字来创建对象,则一定会(在堆区)创建一个新的对象

​ c.使用直接指定或者使用纯字符串串联来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但绝不会在堆栈区再去创建该String对象。

​ d.使用包含变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。最后指向堆内存中的对象

例如:

public class StringTest {
	public static void main(String args[]) {
		// 在池中和堆中分别创建String对象"abc",s1指向堆中对象
		String s1 = new String("abc");
		// s2直接指向池中对象"abc"
		String s2 = "abc";
		// 在堆中为"abc"创建新对象,s3指向该对象
		String s3 = new String("abc");
		// 在池中创建对象"ab" 和 "c",并且s4指向池中对象"abc"
		String s4 = "ab" + "c";
		// c指向池中对象"c"
		String c = "c";
		// 在堆中创建新的对象"abc",并且s5指向该对象
		String s5 = "ab" + c;
		System.out.println("------------实串-----------");
		System.out.println(s1 == s2); // false
		System.out.println(s1 == s3); // false
		System.out.println(s2 == s3); // false
		System.out.println(s2 == s4); // true
		System.out.println(s2 == s5); // false
	}
}

面试题:请解释String对象的两种实例化方式的区别?

· String对象的实例化方式有两种:一种是直接赋值,另外一种是通过构造方法完成;

· 直接赋值:只开辟一个堆内存空间,而且采用了共享设计模式,可以自动的入池,以备下次对象继续使用;

· 构造方法:会开辟两块内存空间,其中有一块空间将成为垃圾,而且不会自动入池,但是可以使用intern()方法进行手工入池;

·从开发角度而言,很明显使用直接赋值的方式会更好一些。

2.1.2 String的匿名对象

双引号引起来的一个字符串常量就是一个String的匿名对象

例如 "abc"

2.1.3 字符串的运算

字符串类型的数据与其他数据类型做运算时,结果一定是字符串类型

例如:

​ String s3 = “abc” + “d”;

​ String s4 = s3 + 5; //abcd5

2.1.4 字符串的比较

1、”==”表示判断该两个字符串是否为同一对象,即在内存中的地址是否一样。如果一样则返回true 否则返回false; 和我们通常的是否为同一对象的是一样的。

2、boolean equals(ObjectanObject) 将此字符串与指定的对象比较。注意此时比较的是内容是否相等(字符串类对此方法进行了覆写)。

​ 例如:String s1= new String(“abc”); String s2 = “abc”

​ 则:s1==s2 //false

​ s1.equals(s2); //true

1、 boolean equalsIgnoreCase(StringanotherString) 将此 String 与另一个 String 比较,不考虑大小写。

例如:”abc”.equalsIgnoreCase**(“AbC”); // true**

5、int compareTo(Stringvalue) 按字典顺序比较两个字符串。如果两个字符串相等,则返回 0;如果字符串在参数值之前,则返回值小于 0;如果字符串在参数值之后,则返回值 大于 0

6、int compareToIgnoreCase(String val) 按字典顺序比较两个字符串,不考虑大小写

7、boolean startsWith(String value) 检查一个字符串是否以参数字符串开始。

8、boolean endsWith(String value) 检查一个字符串是否以参数个字符串结束。

2.1.5 字符串的不可改变

字符串的内容一旦申明,就不能被改变

做类似于+=的操作后,实际上是指向了新的地址,原来的空间里面的内容还是没有改变

如果字符串内容经常发生改变,建议使用StringBuffer

2.1.6 字符串的常用方法

1.字符与字符串:
public String(char[] value)--------------------------全部字符数组变为String类
public String(char[] value,int offset,int count)-----部分字符数组变为String
public char charAt(int index)------------------------返回指定位置上的字符
public char[] toCharArray()--------------------------字符串变为字符数组
2.字节数组与字符串:
public String(byte[] bytes)--------------------------全部字节数组变为字符串
public String(byte[] bytes,int offset,int length)----部分字节数组变为字符串
public byte[] getBytes()-----------------------------字符串变为字节数组(常结合IO流使用)
public byte[] getBytes(String charsetName)throws UnsupportedEncodingException-----------------转码
3.字符串比较:
public boolean equals(String anObject)---------------字符串内容的比较,区分大小写
public boolean equalsIgnoreCase(String anotherString)不区分大小写完成字符串内容的比较
public int compareTo(String anotherString)-----------判断字符串的大于,小于,等于
4.字符串检索:
public boolean contains(String s)--------------------判断指定的子字符串是否存在
public int indexOf(String str)-----------------------从头查找指定的子字符串是否存在,存在则返回字符串的索引,不存在则返回-1
public int indexOf(String str,int fromIndex)---------从指定位置开始检索,没找到则返回-1
public int lastIndexOf(String str)-------------------从后向前查找字符串的位置
public int lastIndexOf(String str,int fromIndex)-----从指定位置开始由后向前查找
public boolean startsWith(String prefix)-------------判断是否以指定字符串开头
public boolean endsWith(Sting suffix)----------------判断是否以指定字符串结尾
5.字符串替换:
public String replaceAll(String regex,String replacement)满足条件的内容全部替换
public String replaceFirst(String regex,String replacement)替换第一个满足条件的内容
6.字符串截取:
public String subString(int beginindex)--------------从beginindex索引开始截取到尾
public String subString(int beginindex,int endindex)-截取中间的部分内容
7.字符串拆分:
public String[] split(String regex)------------------全拆分
public String[] split(String regex,int limit)--------拆分成指定的个数
8.其他方法:
public boolean isEmpty()-----------------------------判断是否是空字符串,不是null
public int length()----------------------------------取得字符串内容的长度
public String toLowerCase()--------------------------所有内容变为小写
public String toUpperCase()--------------------------所有内容变为大写
public String trim()--------------------------------去掉左右空格,中间的无法去掉

2.2 StringBuffer类

2.2.1 为什么使用StringBuffer类

字符串的不变性:

  1. 一个String对象的长度是固定的,不能改变它的内容,或者是附加新的字符到String对象中。
  2. 您也许会使用+来串联字符串以达到附加新字符或字符串的目的,但+会产生一个新的String对象。
  3. 如果程序对这种附加字符串的需求很频繁,系统会频繁在内存中创建String对象,造成性能下降。所以并不建议使用+来进行频繁的字符串串联。应该使用java.lang.StringBuffer类。

2.2.2 StringBuffer的使用

长度经常变化的字符串,可以考虑使用StringBuffer

//建议长度经常变化的字符串,采用StringBuffer

StringBuffer buffer = newStringBuffer();

buffer.append("hello");

buffer.append("world");

2.2.3 StringBuffer和StringBuilder

​ StringBuilder与StringBuffer的用法完全一致,唯一的区别是StringBuffer是线程安全的,而StringBuilder不是线程安全的。所以StringBuilder的性能要比StringBuffer要好。

​ 单线程推荐使用StringBuilder,多线程使用StringBuffer。

猜你喜欢

转载自blog.csdn.net/qian_qian_123/article/details/82354424