String类 ---java

目录

一. 常用的字符串的构造

 二. 字符串的源代码

三. 字符串比较  

1. ==  是不能比较字符串的值的

​编辑 2.比较两个字符串 --- compareTo()

 3. 忽略大小写比较 ---compareToIgnoreCase()

四. 字符串转化

1. 数字转字符串 valueOf()

2. 字符串转数字

3. 小写转大写  toUpperCase()

4. 大写转小写  toLowerCase()

5. 字符串转数组  .toCharArray() 

6. 数组转字符串 ---使用构造方法初始化

7. 格式化 

五. 字符串替换 

六. 字符串拆分

 七. 字符串截取

八. 其他操作方法

九. 字符串的修改

StringBuffer和StringBuilder


一. 常用的字符串的构造

1. 使用常量串构造

String s1 = "hello world" ;
System . out . println ( s1 );

2. 直接newString对象

String s2 = new String ( "hello world" );
System . out . println ( s2 );

 3. 使用字符数组

char [] array = { 'h' , 'e' , 'l' , 'l' , 'o' };
String s3 = new String ( array );
System . out . println ( s3 );

 注: Java中" "引起来的也是String类型对象。

// 打印 "hello" 字符串 (String 对象 ) 的长度
System . out . println ( "hello" . length ());

 二. 字符串的源代码

String类 ---java_第1张图片

我们可以看到,

1. String是引用类型,内部并不存储字符串本身字符串实际保存在字符数组中 

例如:

String s1 = new String ( "hello" );
String s2 = new String ( "world" );
String s3 = s1 ;
//这组代码表示是s1 s2 引用的不同的对象, s1 s3引用的是同一对象
简单画图理解一下:(省略了常量池)
String类 ---java_第2张图片

2.String类被final修饰,表明该类不能被继承

3. value被修饰被final修饰,表明value自身的值不能改变,即不能引用其它字符数组,但是其引用空间中的内容可以修改。
public static void main ( String [] args ) {
final int array [] = { 1 , 2 , 3 , 4 , 5 };
array [ 0 ] = 100 ;//引用空间中的内容可以修改
// array = new int[]{4,5,6}; // 编译报错: Error:(19, 9) java: 无法为最终变量 array 分配值
}

 4.String是一种不可变对象. 字符串中的内容是不可改变。字符串不可被修改,  原因是因为字符串存储在字符数组中, 而数组是被private修饰的, 没有设置公开get或set方法, 所以不能修改!

三. 字符串比较  

1. ==  是不能比较字符串的值的

对于内置类型, == 比较的是变量中的值;
对于引用类型,    == 比较的是两个引用变量是否引用的是同一对象, 即比较的是地址
String s1 = new String ( "hello" );
String s2 = new String ( "hello" );
String s3 = new String ( "world" );
String s4 = s1 ;
System . out . println ( s1 == s2 ); // false
System . out . println ( s2 == s3 ); // false
System . out . println ( s1 == s4 ); // true

 观察下述代码:

String类 ---java_第3张图片

String类 ---java_第4张图片 像上述这种初始化方法属于直接赋值, 通过直接赋值所创建的对象直接是方法区中的常量池中的字符串常量。在存放数据之前, 会检查是否已经有该值, 如果有就不再重复存放了. 

所以上述str1和str2 实际上指向的都是常量池中的"good", 是同一块地址

String类 ---java_第5张图片

String类 ---java_第6张图片

而像上述这样, 属于new对象, 是通过String类的构造方法对其进行初始化, 存放在java虚拟机的堆内存,堆内存里存放的是new对象的地址,字符串常量存放在方法区的常量池中 

构造方法:

String类 ---java_第7张图片

我们画图理解一下: 

String类 ---java_第8张图片

String类 ---java_第9张图片String类 ---java_第10张图片

 2.比较字符串是否相等 --- equals() 

String 类重写了父类 Object equals 方法, Object equals 默认按照 == 比较

使用方法:

String类 ---java_第11张图片 返回类型是boolean类型String类 ---java_第12张图片

查看String类中equals()中的实现方法:

String类 ---java_第13张图片 2.比较两个字符串 --- compareTo()

equals 不同的是, equals 返回的是 boolean 类型,而 compareTo 返回的是 int 类型。具体比较方式:
1. 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值(ASCII码)
2. 如果前 k 个字符相等 (k 为两个字符长度最小值 ) ,返回值两个字符串长度差值
public static void main ( String [] args ) {
        String s1 = new String ( "abc" );
        String s2 = new String ( "ac" );
        String s3 = new String ( "abc" );
        String s4 = new String ( "abcdef" );
        System . out . println ( s1 . compareTo ( s2 )); // 不同输出字符差值  b-c= -1
        System . out . println ( s1 . compareTo ( s3 )); // 相同输出 0
        System . out . println ( s1 . compareTo ( s4 )); // k 个字符完全相同,输出长度差值 -3
}

 3. 忽略大小写比较 ---compareToIgnoreCase()

compareTo 方式相同,但是忽略大小写比较
public static void main ( String [] args ) {
        String s1 = new String ( "abc" );
        String s2 = new String ( "ac" );
        String s3 = new String ( "ABc" );
        String s4 = new String ( "abcdef" );
        System . out . println ( s1 . compareToIgnoreCase ( s2 )); // 不同输出字符差值 -1
        System . out . println ( s1 . compareToIgnoreCase ( s3 )); // 相同输出 0
        System . out . println ( s1 . compareToIgnoreCase ( s4 )); // k 个字符完全相同,输出长度差值 -3
}

 四. 字符串查找

字符串查找也是字符串中非常常见的操作,String类提供的常用查找的方法:

String类 ---java_第14张图片

注意:上述方法都是实例方法。 

public static void main ( String [] args ) {
        String s = "aaabbbcccaaabbbccc" ;
        System . out . println ( s . charAt ( 3 )); // 'b'
        System . out . println ( s . indexOf ( 'c' )); // 6
        System . out . println ( s . indexOf ( 'c' , 10 )); // 15
        System . out . println ( s . indexOf ( "bbb" )); // 3
        System . out . println ( s . indexOf ( "bbb" , 10 )); // 12
        System . out . println ( s . lastIndexOf ( 'c' )); // 17
        System . out . println ( s . lastIndexOf ( 'c' , 10 )); // 8
        System . out . println ( s . lastIndexOf ( "bbb" )); // 12
        System . out . println ( s . lastIndexOf ( "bbb" , 10 )); // 3

 }

四. 字符串转化

1. 数字转字符串 valueOf()

String s1 = String . valueOf ( 1234 );
String s2 = String . valueOf ( 12.34 );
String s3 = String . valueOf ( true );
String s4 = String . valueOf ( new Student ( "Hanmeimei" , 18 ));//可以传任意参数
System . out . println ( s1 );
System . out . println ( s2 );
System . out . println ( s3 );
System . out . println ( s4 );

2. 字符串转数字

// Integer Double 等是 Java 中的包装类型
int data1 = Integer . parseInt ( "1234" );
double data2 = Double . parseDouble ( "12.34" );
System . out . println ( data1 );
System . out . println ( data2 );

3. 小写转大写  toUpperCase()

public static void main ( String [] args ) {
        String s1 = "hello" ;
        String str = " hello%$$%@#$%world 哈哈哈 " ;
        System . out . println ( s1 . toUpperCase ());  
        System . out . println ( str . toUpperCase ());
}
String类 ---java_第15张图片
注:只转字母

4. 大写转小写  toLowerCase()

public static void main ( String [] args ) {
        String s2 = "HELLO" ;
        String str = " HELLO%$$%@#$%WORLD  哈哈哈 " ;
        System . out . println ( s2 . toLowerCase ());
        System . out . println ( s tr. toLowerCase ());
}
String类 ---java_第16张图片

5. 字符串转数组  .toCharArray() 

public static void main ( String [] args ) {
        String s = "hello" ;
        char [] ch = s . toCharArray ();
        for ( int i = 0 ; i < ch . length ; i ++ ) {
                System . out . print ( ch [ i ]);
        }
}

6. 数组转字符串 ---使用构造方法初始化

char [] array = { 'h' , 'e' , 'l' , 'l' , 'o' };
String s3 = new String ( array );
System . out . println ( s3 );

7. 格式化 

public static void main ( String [] args ) {
        String s = String . format ( "%d-%d-%d" , 2019 , 9 , 14 );
        System . out . println ( s );
}
String类 ---java_第17张图片

 注:所有的对字符串的操作, 都是新创建了一个对象,不影响原来的字符串!!!

五. 字符串替换 

使用一个指定的新的字符串替换掉已有的字符串数据,可用的方法如下:
String类 ---java_第18张图片
String str = "helloworld" ;
System . out . println ( str . replaceAll ( "l" , "_" ));
System . out . println ( str . replaceFirst ( "l" , "_" ));
//结果
he__owor_d
he_loworld

注意事项: 由于字符串是不可变对象, 替换不修改当前字符串, 而是产生一个新的字符串. 

六. 字符串拆分

可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串。String类 ---java_第19张图片

//全部拆分
String str = "hello world hello bit" ;
String [] result = str . split ( " " ) ; // 按照空格拆分
for ( String s : result ) {
        System . out . println ( s );
}
String类 ---java_第20张图片
//部分拆分
String str = "hello world hello bit" ;
String [] result = str . split ( " " , 2 ) ;
for ( String s : result ) {
        System . out . println ( s );
}
String类 ---java_第21张图片

拆分是特别常用的操作. 一定要重点掌握. 另外有些特殊字符作为分割符可能无法正确切分, 需要加上转义.

1. 字符 "|"  "*"  "+"  "." 都得加上转义字符,前面加上 "\\" .
 String str = "192.168.1.1" ;
String [] result = str . split ( "\\." ) ;
for ( String s : result ) {
        System . out . println ( s );
}
String类 ---java_第22张图片
2. 而如果是 "\" ,那么就得写成 "\\\\" .
3. 如果一个字符串中有多个分隔符,可以用 "|" 作为连字符 .
String str1  = "name=zhangsan&age=18" ;
String [] result1 = str1 . split ( "&|=" ) ;
for ( String s : result1 ) {
        System . out . println ( s );
}
String类 ---java_第23张图片

上述也可以写成多重拆分:

String str = "name=zhangsan&age=18" ;
String [] result = str . split ( "&" ) ;
for ( int i = 0 ; i < result . length ; i ++ ) {
        String [] temp = result [ i ]. split ( "=" ) ;
        System . out . println ( temp [ 0 ] + " = " + temp [ 1 ]);
}

 七. 字符串截取

从一个完整的字符串之中截取出部分内容。可用方法如下:
String类 ---java_第24张图片

String str = "helloworld" ;
System . out . println ( str . substring ( 5 ));
System . out . println ( str . substring ( 0 , 5 ));
String类 ---java_第25张图片
注:
1. 索引从 0 开始
2. 注意前闭后开区间的写法 , substring(0, 5) 表示包含 0 号下标的字符 , 不包含 5 号下标  

八. 其他操作方法

去掉字符串中的左右空白字符(空格, 换行, 制表符等), 保留中间空格---trim()  

String str = " hello world " ;
System . out . println ( "[" + str + "]" );
System . out . println ( "[" + str . trim () + "]" );
String类 ---java_第26张图片

九. 字符串的修改

public static void main ( String [] args ) {
String s = "hello" ;
s += " world" ;
System . out . println ( s ); // 输出: hello world
}

上述代码, 虽然实现了字符串的修改, 但是前面我们知道, 对字符串的操作都是创建了一个新的对象, 效率十分低下.  

所以我们要介绍下面两种类: StringBuffer和StringBuilder

StringBuffer和StringBuilder

由于 String 的不可更改特性,为了方便字符串的修改, Java 中又提供 StringBuilder StringBuffer 类。这两个类大部分功能是相同的,这里介绍 StringBuilder 常用的一些方法. 

 String类 ---java_第27张图片

举例:

public static void main ( String [] args ) {
StringBuilder sb1 = new StringBuilder ( "hello" );
StringBuilder sb2 = sb1 ;
// 追加:即尾插 --> 字符、字符串、整形数字
sb1 . append ( ' ' ); // hello
sb1 . append ( "world" ); // hello world
sb1 . append ( 123 ); // hello world123
System . out . println ( sb1 ); // hello world123
System . out . println ( sb1 == sb2 ); // true
System . out . println ( sb1 . charAt ( 0 )); // 获取 0 号位上的字符 h
System . out . println ( sb1 . length ()); // 获取字符串的有效长度 14
System . out . println ( sb1 . capacity ()); // 获取底层数组的总大小
sb1 . setCharAt ( 0 , 'H' ); // 设置任意位置的字符 Hello world123
sb1 . insert ( 0 , "Hello world!!!" ); // Hello world!!!Hello world123
System . out . println ( sb1 );
System . out . println ( sb1 . indexOf ( "Hello" )); // 获取 Hello 第一次出现的位置
System . out . println ( sb1 . lastIndexOf ( "hello" )); // 获取 hello 最后一次出现的位置
sb1 . deleteCharAt ( 0 ); // 删除首字符
sb1 . delete ( 0 , 5 ); // 删除 [0, 5) 范围内的字符
String str = sb1 . substring ( 0 , 5 ); // 截取 [0, 5) 区间中的字符以 String 的方式返回
System . out . println ( str );
sb1 . reverse (); // 字符串逆转
str = sb1 . toString (); // StringBuffer String 的方式返回
System . out . println ( str );
}
从上述例子可以看出: String StringBuilder 最大的区别在于 String的内容无法修改,而StringBuilder的内容可以修改 频繁修改字符串的情况考虑使用StringBuilder

 

注意:
a.  StringStringBuilder 类不能直接转换。如果要想互相转换,可以采用如下原则 :
    1. String 变为 StringBuilder:
    利用 StringBuilder 的构造方法
String类 ---java_第28张图片
    利用 StringBuilder 的append()方法
String类 ---java_第29张图片
    2. StringBuilder 变为 String:
    调用 toString() 方法
String类 ---java_第30张图片
b. StringBuffer和StringBuilder不能直接赋值
面试题:
String StringBuffer StringBuilder 的区别:
1. String 的内容不可修改, StringBuffer StringBuilder 的内容可以修改 .
2. StringBuffer StringBuilder 大部分功能是相似的.
3. StringBuffer 采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作.

你可能感兴趣的:(javaSE,java,开发语言)