Java String类

119 阅读7分钟

1.string类的理解(以JDK8为例说明)

1.1 类的声明

public final class String
        implements java.io.Serializable, Comparable<String>, CharSequence
final:String是不可被继承的
Serializable:可序列化的接口。凡是实现此接口的类的对象就可以通过网络或本地流进行数据的传输。
Comparable:凡是实现此接口的类,其对象都可以比较大小。

1.2 内部声明的属性

private final char value[]; //存储字符串数据的容器
final:指明此value数组一旦初始化,其地址就不可变(比如value存储的是“hello”,现在要改成“hello world”,
      不能在当前string类的对象上修改,只能重新创建一个string类的对象来调用value存储“hello world”)

1.3 字符串常量的存储位置

字符串常量都存储在字符串常量池(stringTable)中。
字符串常量池不允许存放两个相同的字符串常量。
字符串常量池,在不同的jdk版本中,存放位置不同。jdk7之前,字符串常量池存放在方法区,jdk7及之后:字符串常量池存放在堆空间。

1.4 String的不可变性

1.当对字符串变量重新赋值时,需要重新指定一个字符串常量的位置进行赋值,不能在原有的位置修改
2.当对现有的字符中进行拼接操作时,需要重新开辟空间保存拼接以后的字符中,不能在原有的位置修改
3.当调用字符中的replace() 替换现有的某个字符时,需要重新开辟空间保存修改以后的字符串,不能在原有的位置修改

public void test01(){
    String s1 = "java";
    String s2 = "java";    
    s2 = "hello";
    System.out.println(s1);  //java
    System.out.println(s2);  //hello
}

public void test02(){
    String s1 = "java";
    String s2 = "java";
    s2 += "hello";
    System.out.println(s1);  //java
    System.out.println(s2);  //javahello
}


public void test03(){
    String s1 = "java";
    String s2 = "java";
    
    String s3 = s2.replace('a','e')
    
    System.out.println(s1);  //java
    System.out.println(s2);  //java
    System.out.println(s3);  //jeve
}

2. String 实例化的两种方式

第一种方式:String s1 = "hello";
第二种方式:String s2 = new String("hello"); 在内存中创建了两个对象。一个是堆空间中new的对象,另一个是在字符串常量池中生成的字面量。

public void test01(){
    person p1 = new person();
    person p2 = new person();

    p1.name = "Tom";
    p2.name = "Tom";
    System.out.println(p1.name == p2.name);//true

    p1.name = "Jerry";
    System.out.println(p1.name == p2.name);//false
}

3. String的连接操作:+

情况1:常量 +常量:结果仍然存储在字符串常量池中。此时的常量可能是字面量,也可能是 final 修饰的常量。
情况2:常量+变量或变量变量,都会通过ne的方式创建一个新的字符串,返回堆空间中此字符串对象的地划。
情况3:调用字符串的intern():返回的是字符串常量池中字司量的地址。

public void test02() {
    String s1 = "hello";
    String s2 = "world";
    String s3 = "helloworld";
    String s4 = "hello" + "world"; //在实际上,"hello" + "world" = “helloworld“,编译器以默认拼接完成。
    String s5 = s1 +"world";//通过查看字节码文件发现调用了StringBuilder的toString()---> new String()
    String s6 ="hello"+ s2;
    String s7 = s1 + s2;

    System.out.println(s3 == s4);//true
    System.out.println(s3 == s5);//false
    System.out.println(s3 == s6);//false
    System.out.println(s3 == s7);//false
    System.out.println(s5 == s6);//false
    System.out.println(s5 == s7);//false

    String s8 = s5.intern(); //intern():返回的是字符串常量池中字面量的地址
    System.out.println(s3 == s8);//true
}

情况4:concat(xxx):不管是常量调用此方法,还是变量调用,同样不管参数是常量还是变量。总之,调用完concat()方法后都返回一个新new的对象。

public void test03() {
        String s1 = "hello";
        String s2 = "world";
        String s3 = s1.concat(s2);
        String s4 = "hello".concat("world");
        String s5 = s1.concat("world");
        
        System.out.println(s3 == s4);//false
        System.out.println(s3 ==s5);//false
        System.out.println(s4 == s5);//false
}

4. String的构造器和常用方法

4.1 构造器

public String(): 初始化新创建的 String 对象,以使其表示空字符序列。

String s = new String();

public String(String original): 传递一个字符串,根据传递的字符串再创建一个字符串对。

String s = new String("hello world");

public String(char[] value): 通过当前参数中的字符数组来构造新的String。

String str = new String(new char[]{'a','b'})

public String(char[] valve,int offset,int count):通过字符数组的一部分来构造新的String。value-作为字符源的数组;offset-初始偏移量;count-长度。

String str = new String(new char[]{'a','b'},1,1); System.out.println(str);

public String(byte[] bytes):传递一个字节数组,根据字节数组再创建字符串对象

String bt = new String(new byte[]{'t','u','t'});

public String(byte[] bytes,Strrng charsetName):通过使用指定的字符集解码当前参数中的字节数组来构造。

4.2 常用方法

(1)boolean isEmpty(): 字符中是否为空
(2) int Length(): 返字符中的长度
(3) String concat(xx): 拼接
(4)boolean equals(bject obj): 比较字符中是否相等,区分大小写
(5)boolean equalsIgnoreCase(Object obj): 比较字符申是否相等,不区分大小写
(6)int compareTo(String other): 比较字符大小,区分大小写,按照Unicode编码值比较大小
(7)int compareToIgnoreCase(String other): 比较字符中大小,不区分大小写
(8) String toLowerCase():将字符中大写字母转为小写
(9)String toUpperCase():将字符中中小写字母转为大写
(10) String trim(): 去字符中前后空白符
(11) boolean contains(xx): 是否包含xx
(12) int indexof(xx): 从前往后找当前字符串中xx,即如果有返回第一次出现的下标,要是没有返回-1
(13) int indexof(String str, int fromindex): 返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
(14)int lastlndexof(xx): 从后往前找当前字符串中xx,即如果有返回最后一次出现的下标,要是没有返回-1
(15) int lastlndexof(String str, int fromindex): 返回指定子字符在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
(16)String substring(int beginlndex): 返回一个新的字符串,它是此字符的从beginlndex开始截取到最后的一个子字符串。
(17) String substring(int beginindex,int endindex): 返回一个新字符串,它是此字符串从beginindex开始截取到endindex(不包含)的一个子字符串。
(18) char charAt(index): 返回[index]位置的字符
(19)char[] toCharArray(): 将此字符串转换为一个新的字符数组返回
(20)static String valueOf(char[] data) : 返回指定数组中表示该字符序列的 String
(21)static String value0fchar[] data,int offset,int count): 返回指定数组中表示该字符序列的 String
(22)static String copyValueof(char[] data): 返回指定数组中表示该字符序列的 String
(23) static String copyValueOf(charl] data,int offset, int count): 返回指定数组中表示该字符序列的 String
(24) boolean startswith(xx): 测试此字符串是否以指定的前缀开始
(25) boolean startsWith(String prefix,int toffset): 测试此字符串从指定索开始的子字符串是否以指定前缀开始
(26) boolean endswith(xx): 测试此字符串是否以指定的后缀结束
(27) String replace(char oldChar, char newChar): 返回一个新的字符串,它是通过用newChar 替换此字符串中出现的所有 oldchar得到的。不支持正则。
(28) String replace(CharSequence target, CharSequence replacement): 使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。
(29) String replaceAll(String regex, String replacement): 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
(30) String replaceFirst(String regex, String replacement): 使用给定的replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。
String s1 = "";
     System.out.println(s1.isEmpty());// true
     String s2 = null;
//     System.out.println(s2.isEmpty());//报空指针异常


     String s3 = "hello";
     System.out.println(s3.length());// 5

     String s4 = "java";
     System.out.println(s3.concat(s4));//hellojava

     String s5 = "hello";
     System.out.println(s3.equals(s5));//true
     String s6 = "HeLLo";
     System.out.println(s3.equalsIgnoreCase(s6));//true

     //返回参与比较的前后两个字符串的asc码的差值,如果两个字符串首字母不同,则该方法返回首字母的asc码的差值
     //参与比较的两个字符串如果首字符相同,则比较下一个字符,直到有不同的为止,返回该不同的字符的asc码差值
     //如果两个字符串不一样长,可以参与比较的字符又完全一样,则返回两个字符串的长度差值
     System.out.println(s5.compareTo(s4));//-2
     

     String s7 = "  he l l    o    ";
     System.out.println("****" + s7.trim() + "****");//****he l l    o****

(16)(17)
String s1 = "稀土掘金";
System.out.println(s1.substring(2));//掘金
System.out.println(s1.substring(2,4));//掘金

(20)(22)
String s2 = String.value0f(new char[]{'a',"b','c'});
String s3 = String.copyValue0f(new char[]{'a',b',c'});
System.out.println(s2);//abc
System.out.println(s3);//abc
System.out.println(s2 == s3);//false

(27)(28)
String s1 = "hello";
String s2 = s1.replace( 'l','w' );
System.out.println(s1);//hello
System.out.println(s2);//hewwo
String s3 = s1.replace( "ll","wwww");
System.out.println(s3);//hewwwwo

(29)
String strTmp = new String("BBYY"); 
strTmp = strTmp.replaceAll ("\\D", "Y");//YYYY
//将所有数字字符替换成Y,将B当成ASCII码数字