String,StringBuffer,StringBuilder类汇总

前言

字符串Java中非常重要的部分, 这里包含了大量的处理方法以及性质特点, 这篇文章对常用的String类, StringBuffer类, StringBuilder类相关知识点进行汇总.

String类

两个重要特点

String 常量池

常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。Java为了提高性能,静态字符串(字面量/常量/常量连接的结果)在常量池中创建,并尽量使用同一个对象,重用静态字符串。对于重复出现的字符串直接量,JVM会首先在常量池中查找,如果常量池中存在即返回该对象。

例:

1
2
3
4
5
6
7
8
9
10
11
public class test1 {
public static void main(String[] args){
String str1 = "Hello";//生成了1个对象"Hello"
//不会创建新的String对象,而是使用常量池中已有的"Hello",
String str2 = "Hello";
System.out.println(str1 == str2); //true
//使用new关键字会创建新的String对象,不管常量池里面有没有相同的值
String str3 = new String("Hello");//生成了2个对象"Hello"和new String("Hello")
System.out.println(str1 == str3); //false
}
}

String 对象不可变

String是常量,其对象一旦构造就不能再被改变。换句话说,String对象是不可变的,每一个看起来会修改String值的方法,实际上都是创造了一个全新的String对象,以包含修改后的字符串内容。而最初的String对象则丝毫未动。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class StringTest02 {
public static void main(String[] args) {
String s = "hello";
String newS = StringTest02.append(s);
System.out.println("String append--->" + s.toString());

StringBuilder sb = new StringBuilder("hello");
StringBuilder newSb = StringTest02.append(sb);
System.out.println("StringBuilder append--->" +sb.toString());
}

public static String append(String s) {
s += "kitty";
return s;
}

public static StringBuilder append(StringBuilder sb) {
return sb.append("kitty");
}
}

输出为:

1
2
String append--->hello
StringBuilder append--->hellokitty

由上面的例子可见StringBuilder sb的值被改变了,而String s的值没有变,所以String不可变的安全性就体现出来了

String 类的方法

构造方法

1、public String()
无参构造方法,用来创建空字符串的String对象。

1
String str1 = new String();

2、public String(String value)
用已知的字符串value创建一个String对象。

1
2
String str2 = new String("qwer"); 
String str3 = new String(str2);

3、public String(char[] value)
用字符数组value创建一个String对象。

1
2
char[] value = {"a","b","c","d"};
String str4 = new String(value);//相当于String str4 = new String("abcd");

4、public String(char chars[], int startIndex, int numChars)
用字符数组chars的startIndex开始的numChars个字符创建一个String对象。

1
2
char[] value = {"a","b","c","d"};
String str5 = new String(value, 1, 2);//相当于String str5 = new String("bc");

5、public String(byte[] values)
用比特数组values创建一个String对象。

1
2
byte[] strb = new byte[]{65,66,67,68};
String str6 = new String(strb);//相当于String str6 = new String("ABCD");

6、public String(byte[] values,int startIndex, int numChars)
用字符数组byte的startIndex开始的numChars个字符创建一个String对象。

1
2
byte[] strb = new byte[]{65,66,67,68};
String str6 = new String(strb,0,1);//相当于String str6 = new String("A");

常用方法

1、length()
返回字该字符串的长度

2、charAt(int indext)
求字符串某一位置的字符,index必须>=0并且<= length()-1

3、截取字符串

  • substring(int beginIndex)
    该方法从beginIndex位置起(包含这个位置)到最后截取一个字符串返回。
    [beginIndex,最后]
  • substring(int beginIndex,endIndex)
    该方法从beginIndex位置起(包含这个位置)到endIndex - 1截取一个字符串返回。
    [beginIndex,endIndex - 1]
    例:
1
2
3
String str1 = new String("abcdefgkl");
String str2 = str1.substring(2);//str2 = "cdefgkl"
String str3 = str1.substring(2,5);//str3 = "cde"

4、字符串比较

  • public int compareTo(String anotherString)
    该方法是对字符串内容按字典顺序进行大小比较,通过返回的整数值指明当前字符串与参数字符串的大小关系。若当前对象比参数大则返回正整数,反之返回负整数,相等返回0。其比较规则是:拿出字符串的第一个字符与参数的第一个字符进行比较,如果两者不等,比较结束,返回两者的ascii差。这里有一点需要注意:如果两个字符串的长度不同,并且一个字符串与另一个字符串的前面N个字符相等,那么这个方法返回返回两个字符串长度之差。
  • public int compareToIgnore(String anotherString)
    与compareTo方法相似,但忽略大小写。
  • public boolean equals(Object anotherObject)
    比较当前字符串和参数字符串,在两个字符串相等的时候返回true,否则返回false。
  • public boolean equalsIgnoreCase(String anotherString)
    与equals方法相似,但忽略大小写。
    例:
1
2
3
4
5
6
7
8
9
10
11
12
String s1 = "abcd"; 
String s2 = "abce";
String s3 = "ABC";
String s4 = "abcdefg";
String s5 = "abc";
System.out.println(s1.compareTo(s2));
System.out.println(s1.compareTo(s3));
System.out.println(s4.compareTo(s1));
System.out.println(s4.compareTo(s2));
System.out.println(s3.compareToIgnoreCase(s5));
System.out.println(s3.equals(s5));
System.out.println(s3.equalsIgnoreCase(s5));

输出为:

1
2
3
4
5
6
7
-1
32
3
-1
0
false
true

5、字符串连接

  • public String concat(String str)
    将参数中的字符串str连接到当前字符串的后面,效果等价于”+”。

6、字符串中单个字符查找

  • public int indexOf(int ch/String str)
    用于查找当前字符串中字符或子串,返回字符或子串在当前字符串中从左边起首次出现的位置,若没有出现则返回-1。
  • public int indexOf(int ch/String str, int fromIndex)
    改方法与第一种类似,区别在于该方法从fromIndex位置向后查找。
  • public int lastIndexOf(int ch/String str)
    该方法与第一种类似,区别在于该方法从字符串的末尾位置向前查找。
  • public int lastIndexOf(int ch/String str, int fromIndex)
    该方法与第二种方法类似,区别于该方法从fromIndex位置向前查找。
    例:
1
2
3
4
5
6
String str = "I am a good student";
System.out.println(str.indexOf('a'));
System.out.println(str.indexOf("good"));
System.out.println(str.indexOf("w", 2));
System.out.println(str.lastIndexOf("a"));
System.out.println(str.lastIndexOf("a", 3));

输出为:

1
2
3
4
5
2
7
-1
5
2

7、字符串中字符的大小写转换

  • public String toLowerCase()
    返回将当前字符串中所有字符转换成小写后的新串
  • public String toUpperCase()
    返回将当前字符串中所有字符转换成大写后的新串

8、字符串中字符的替换

  • public String replace(char oldChar, char newChar)
    用字符newChar替换当前字符串中所有的oldChar字符,并返回一个新的字符串。
  • public String replaceFirst(String regex, String replacement)
    该方法用字符replacement的内容替换当前字符串中遇到的第一个和字符串regex相匹配的子串,应将新的字符串返回。
  • public String replaceAll(String regex, String replacement)
    该方法用字符replacement的内容替换当前字符串中遇到的所有和字符串regex相匹配的子串,应将新的字符串返回。
    例:
1
2
3
4
5
String str4 = "asdzxcasd";
System.out.println(str4.replace('a', 'g'));
System.out.println(str4.replace("asd", "fgh"));
System.out.println(str4.replaceFirst("asd", "fgh"));
System.out.println(str4.replaceAll("asd", "fgh"));

输出为:

1
2
3
4
gsdzxcgsd
fghzxcfgh
fghzxcasd
fghzxcfgh

注意:replace和preplaceAll的区别

  1. replace的参数是char和CharSequence,即可以支持字符的替换,也支持字符串的替换(CharSequence即字符串序列的意思,说白了也就是字符串);
  2. replaceAll的参数是regex,即基于规则表达式的替换,比如,可以通过replaceAll(“\d”, “*”)把一个字符串所有的数字字符都换成星号;

其他方法

1、去除首位空格

  • String trim()

    截去字符串两端的空格,但对于中间的空格不处理。

1
2
3
4
String str = " a sd ";
String str1 = str.trim();
int a = str.length();//a = 6
int b = str1.length();//b = 4

2、确认开始或结尾字符串

  • boolean statWith(String prefix)或boolean endWith(String suffix)
    用来比较当前字符串的起始字符或子字符串prefix和终止字符或子字符串suffix是否和当前字符串相同,重载方法中同时还可以指定比较的开始位置offset。
1
2
3
String str = "asdfgh";
boolean a = str.statWith("as");//a = true
boolean b = str.endWith("gh");//b = true

3、包含字符串

  • contains(String str)
    判断参数s是否被包含在字符串中,并返回一个布尔类型的值。
1
2
3
String str = "student";
str.contains("stu");//true
str.contains("ok");//false

4、分隔字符串

  • String[] split(String str)
    将str作为分隔符进行字符串分解,分解后的字字符串在字符串数组中返回。
1
2
String str = "asd!qwe!zxc";
String[] str1 = str.split("!");//str1[0] = "asd";str1[1] = "qwe";str1[2] = "zxc";

字符串与基本类型的转换

1、字符串转换为基本类型

java.lang包中有Byte、Short、Integer、Float、Double类的调用方法:

  • public static byte parseByte(String s)

  • public static short parseShort(String s)

  • public static short parseInt(String s)

  • public static long parseLong(String s)

  • public static float parseFloat(String s)

  • public static double parseDouble(String s)

    例如:

1
2
3
int n = Integer.parseInt("12");
float f = Float.parseFloat("12.34");
double d = Double.parseDouble("1.124");

2、基本类型转换为字符串类型

String类中提供了String valueOf()放法,用作基本类型转换为字符串类型。

  • static String valueOf(char data[])
  • static String valueOf(char data[], int offset, int count)
  • static String valueOf(boolean b)
  • static String valueOf(char c)
  • static String valueOf(int i)
  • static String valueOf(long l)
  • static String valueOf(float f)
  • static String valueOf(double d)
    例如:
1
2
String s1 = String.valueOf(12);
String s1 = String.valueOf(12.34);

StringBuffer, StringBuilder

共同支持的方法

  • public StringBuffer append(String s)
    将指定的字符串追加到此字符序列。
  • public StringBuffer reverse()
    将此字符序列用其反转形式取代。
  • public delete(int start, int end)
    移除此序列的子字符串中的字符。
  • public insert(int offset, int i)
    将 int 参数的字符串表示形式插入此序列中。
  • replace(int start, int end, String str)
    使用给定 String 中的字符替换此序列的子字符串中的字符。
  • int capacity()
    返回当前容量
  • void setCharAt(int index, char ch)
    将给定索引处的字符设置为 ch。
  • void setLength(int newLength)
    设置字符序列的长度

在大部分情况下 StringBuilder > StringBuffer

java.lang.StringBuildejava.lang.StringBuilder一个可变的字符序列是5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。

三者的区别

1、对象的可变与不可变
String对象不可变,StringBuffer和StringBuilder对象可变。

2、 线程是否安全

  • String中的对象是不可变的,也就可以理解为常量,所以线程安全。
  • StringBuffer中的方法大都采用了synchronized关键字修饰,所以是线程安全的。
  • StringBuilder没有对方法进行加同步锁,所以是非线程安全的。

3、 字符串追加速度比较
StringBuilder > StringBuffer > String

4、 StringBuffer和StringBuilder的共同点

  • StringBuffer和StringBuilder有公共的抽象父类AbstractStringBuilder
  • 抽象类与一个接口的区别是:抽象类中可以定义一些子类的公共方法,子类只需要增加新的功能,不需要重复写已经存在的方法;而接口中只是对方法的申明和常量的定义。
  • StringBuilder和StringBuffer的方法都会调用AbstractStringBuilder中的公共方法,如super.append(…)。只是StringBuffer会在方法上加上synchronized关键字,进行同步。
    如果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer

总结

String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用于多线程下在字符缓冲区进行大量操作的情况

-------------本文结束感谢您的阅读-------------
可以请我喝杯奶茶吗