目录
一. 常用的字符串的构造
二. 字符串的源代码
三. 字符串比较
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 ());
我们可以看到,
1. String是引用类型,内部并不存储字符串本身,字符串实际保存在字符数组中
例如:
String s1 = new String ( "hello" );String s2 = new String ( "world" );String s3 = s1 ;//这组代码表示是s1 s2 引用的不同的对象, s1 s3引用的是同一对象简单画图理解一下:(省略了常量池)
2.String类被final修饰,表明该类不能被继承
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方法, 所以不能修改!
String s1 = new String ( "hello" );String s2 = new String ( "hello" );String s3 = new String ( "world" );String s4 = s1 ;System . out . println ( s1 == s2 ); // falseSystem . out . println ( s2 == s3 ); // falseSystem . out . println ( s1 == s4 ); // true
观察下述代码:
像上述这种初始化方法属于直接赋值, 通过直接赋值所创建的对象直接是方法区中的常量池中的字符串常量。在存放数据之前, 会检查是否已经有该值, 如果有就不再重复存放了.
所以上述str1和str2 实际上指向的都是常量池中的"good", 是同一块地址
而像上述这样, 属于new对象, 是通过String类的构造方法对其进行初始化, 存放在java虚拟机的堆内存,堆内存里存放的是new对象的地址,字符串常量存放在方法区的常量池中
构造方法:
我们画图理解一下:
2.比较字符串是否相等 --- equals()
使用方法:
查看String类中equals()中的实现方法:
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= -1System . out . println ( s1 . compareTo ( s3 )); // 相同输出 0System . out . println ( s1 . compareTo ( s4 )); // 前 k 个字符完全相同,输出长度差值 -3}
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 )); // 不同输出字符差值 -1System . out . println ( s1 . compareToIgnoreCase ( s3 )); // 相同输出 0System . out . println ( s1 . compareToIgnoreCase ( s4 )); // 前 k 个字符完全相同,输出长度差值 -3}
四. 字符串查找
字符串查找也是字符串中非常常见的操作,String类提供的常用查找的方法:
注意:上述方法都是实例方法。
public static void main ( String [] args ) {String s = "aaabbbcccaaabbbccc" ;System . out . println ( s . charAt ( 3 )); // 'b'System . out . println ( s . indexOf ( 'c' )); // 6System . out . println ( s . indexOf ( 'c' , 10 )); // 15System . out . println ( s . indexOf ( "bbb" )); // 3System . out . println ( s . indexOf ( "bbb" , 10 )); // 12System . out . println ( s . lastIndexOf ( 'c' )); // 17System . out . println ( s . lastIndexOf ( 'c' , 10 )); // 8System . out . println ( s . lastIndexOf ( "bbb" )); // 12System . out . println ( s . lastIndexOf ( "bbb" , 10 )); // 3}
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 );
// Integer 、 Double 等是 Java 中的包装类型int data1 = Integer . parseInt ( "1234" );double data2 = Double . parseDouble ( "12.34" );System . out . println ( data1 );System . out . println ( data2 );
public static void main ( String [] args ) {String s1 = "hello" ;String str = " hello%$$%@#$%world 哈哈哈 " ;System . out . println ( s1 . toUpperCase ());System . out . println ( str . toUpperCase ());}注:只转字母
public static void main ( String [] args ) {String s2 = "HELLO" ;String str = " HELLO%$$%@#$%WORLD 哈哈哈 " ;System . out . println ( s2 . toLowerCase ());System . out . println ( s tr. toLowerCase ());}
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 ]);}}
char [] array = { 'h' , 'e' , 'l' , 'l' , 'o' };String s3 = new String ( array );System . out . println ( s3 );
public static void main ( String [] args ) {String s = String . format ( "%d-%d-%d" , 2019 , 9 , 14 );System . out . println ( s );}
注:所有的对字符串的操作, 都是新创建了一个对象,不影响原来的字符串!!!
String str = "helloworld" ;System . out . println ( str . replaceAll ( "l" , "_" ));System . out . println ( str . replaceFirst ( "l" , "_" ));//结果he__owor_d
he_loworld
注意事项: 由于字符串是不可变对象, 替换不修改当前字符串, 而是产生一个新的字符串.
可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串。
//全部拆分String str = "hello world hello bit" ;String [] result = str . split ( " " ) ; // 按照空格拆分for ( String s : result ) {System . out . println ( s );}//部分拆分
拆分是特别常用的操作. 一定要重点掌握. 另外有些特殊字符作为分割符可能无法正确切分, 需要加上转义.
上述也可以写成多重拆分:
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 str = "helloworld" ;System . out . println ( str . substring ( 5 ));System . out . println ( str . substring ( 0 , 5 ));注:1. 索引从 0 开始2. 注意前闭后开区间的写法 , substring(0, 5) 表示包含 0 号下标的字符 , 不包含 5 号下标
去掉字符串中的左右空白字符(空格, 换行, 制表符等), 保留中间空格---trim()
String str = " hello world " ;System . out . println ( "[" + str + "]" );System . out . println ( "[" + str . trim () + "]" );
public static void main ( String [] args ) {String s = "hello" ;s += " world" ;System . out . println ( s ); // 输出: hello world}
上述代码, 虽然实现了字符串的修改, 但是前面我们知道, 对字符串的操作都是创建了一个新的对象, 效率十分低下.
所以我们要介绍下面两种类: StringBuffer和StringBuilder
举例:
public static void main ( String [] args ) {StringBuilder sb1 = new StringBuilder ( "hello" );StringBuilder sb2 = sb1 ;// 追加:即尾插 --> 字符、字符串、整形数字sb1 . append ( ' ' ); // hellosb1 . append ( "world" ); // hello worldsb1 . append ( 123 ); // hello world123System . out . println ( sb1 ); // hello world123System . out . println ( sb1 == sb2 ); // trueSystem . out . println ( sb1 . charAt ( 0 )); // 获取 0 号位上的字符 hSystem . out . println ( sb1 . length ()); // 获取字符串的有效长度 14System . out . println ( sb1 . capacity ()); // 获取底层数组的总大小sb1 . setCharAt ( 0 , 'H' ); // 设置任意位置的字符 Hello world123sb1 . insert ( 0 , "Hello world!!!" ); // Hello world!!!Hello world123System . 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 );}
a. String和StringBuilder 类不能直接转换。如果要想互相转换,可以采用如下原则 :1. String 变为 StringBuilder:利用 StringBuilder 的构造方法利用 StringBuilder 的append()方法2. StringBuilder 变为 String:调用 toString() 方法b. StringBuffer和StringBuilder不能直接赋值