字符串
什么是字符串?
字符串是复合数据类型,在Java中,使用非常的广泛;字符串属于对象,JDK 提供了java.lang.String
来对字符串进行创建和操作。
字符串实例化
字面量方式定义
javaString name1 = "一行Java"; String name2 = "一行Java"; String name3 = "一航";
字面量创建的字符串是直接保存在常量池中,常量池中,相同的字符串常量只会存在一个
构造方法定义
javaString name4 = new String("一行Java"); String name5 = new String("一行Java");
构造方法创建的字符串是在堆中保存
比较
javaSystem.out.println(name1 == name2); // true System.out.println(name1 == name4); // false System.out.println(name1 == name5); // false System.out.println(name4 == name5); // false System.out.println(name1.equals(name4)); // true 比较的是值
特点
- 字符串使用
""
来表示; - String声明为final的,不可以被继承;
- 字符串 value 是final修饰,一旦创建,不允许修改;
- 字符串的字符使用Unicode进行编码;
一个字符(不区分字母还是汉字)占两个字节
- String实现了Serializable接口;
说明String支持序列化,支持网络传输
- String实现了Comparable接口;
说明String支持比较大小
String 方法
下面是 String 类支持的方法
charAt
返回指定索引(下标)的字符,下标从0开始,最大位置length()-1;
方法
javapublic char charAt(int index){}
参数
- index:字符对应的下标
返回
下标对应的字符
示例
javapublic static void main(String[] args) { String name = "一行Java"; System.out.println(name.charAt(3)); // a }
示例输出
a
compareTo
按字典顺序,比较两个字符串;
方法
javapublic int compareTo(String anotherString) {}
参数
- anotherString:其他字符串
返回
该方法比较的过程,是对字符的大小(ascii码)逐个比较,相等再下个字符;如果全部字符都相等,则返回0,如果出现不相等,则计算两个字符对应的差值并返回;
示例
javapublic static void main(String[] args) { String s1 = "abc"; String s2 = "abe"; System.out.println(s1.compareTo(s2)); // -2 System.out.println(s2.compareTo(s1)); // 2 }
示例输出
-2
2
差异在c和e两个字符,两个字符的ascii码值相差2,所以输出的结果就是起对应的差值;
compareToIgnoreCase
功能和compareTo(String anotherString)类似,区别在于此方法会忽略大小写
- 示例java示例输出
public static void main(String[] args) { String s1 = "abc"; String s2 = "abC"; System.out.println(s1.compareTo(s2)); // 32 System.out.println(s2.compareToIgnoreCase(s1)); // 0 // 忽略大小写之后,两个字符串就相等了 }
32
0 // 忽略大小写之后,两个字符串就相等了
concat
字符串拼接;将指定字符串连接到此字符串的结尾。
方法
javapublic String concat(String str) {}
参数
- str:要追加的字符串
返回
追加之后的字符串
示例
javapublic static void main(String[] args) { String s1 = "abc"; String s2 = "def"; System.out.println(s1.concat(s2)); // abcdef }
示例输出
abcdef
contentEquals
用户字符串与StringBuffer
进行比较;
方法
javapublic boolean contentEquals(StringBuffer sb) {} public boolean contentEquals(CharSequence cs) {
参数
- sb:要比较的 StringBuffer
- cs:任意实现了
CharSequence
接口的对象
返回
- true:相同
- false:不同
示例
javapublic static void main(String[] args) { String s1 = "abc"; StringBuffer sb1 = new StringBuffer("abc"); StringBuffer sb2 = new StringBuffer("abe"); System.out.println(s1.contentEquals(sb1)); // true System.out.println(s1.contentEquals(sb2)); // false }
示例输出
true
false
copyValueOf
返回指定数组中表示该字符序列的 String
方法
javapublic static String copyValueOf(char[] data) {} // 指定下标及长度 public static String copyValueOf(char[] data, int offset, int count) {}
参数
- char[] data :字符数组
- offset:字符的下标偏移量
- count:长度
返回
返回指定数组中表示该字符序列的字符串。
示例
javapublic static void main(String[] args) { char[] cs = {'h','e','l','l','o',',','e','h','a','n','g',' ','j','a','v','a'}; System.out.println(String.copyValueOf(cs)); // hello,ehang java System.out.println(String.copyValueOf(cs,6,5)); // ehang }
示例输出
hello,ehang java
ehang
startsWith
判断当前字符串是以指定字符串开头;
方法
javapublic boolean startsWith(String prefix) {} public boolean startsWith(String prefix, int toffset) {}
参数
- prefix:要匹配的前缀
- toffset:指定偏移量;默认头开始比较;
返回
- true:是以指定的
prefix
开头 - false:未匹配上
- true:是以指定的
示例
javapublic static void main(String[] args) { String s1 = "一行Java"; System.out.println(s1.startsWith("一行")); // true System.out.println(s1.startsWith("一航")); // false // 表示从s1的第二个字符之后开始比对,是否是以Java开头 System.out.println(s1.startsWith("Java",2)); // true }
示例输出
true
false
true
endsWith
判断当前字符串是否以指定的字符串结尾;
方法
javapublic boolean endsWith(String suffix) {}
参数
- suffix:指定后缀
返回
- true:是以
suffix
结尾 - false:不是以
suffix
结尾
- true:是以
示例
javapublic static void main(String[] args) { String s1 = "一行Java"; System.out.println(s1.endsWith("一行")); // false System.out.println(s1.endsWith("Java")); // true }
示例输出
false
true
equals
将当前字符串与指定的对象比较。anObject 是字符串对象时,会比较当前对象与anObject的值,一样返回true,不一样返回false;
如果 anObject 是其他对象,将直接返回false;
方法
javapublic boolean equals(Object anObject) {}
参数
- anObject:要比较的对象
返回
- true:anObject为String对象,且值和此对象的值一样;
- false:anObject非String对象,或者值不一样;
示例
javapublic static void main(String[] args) { String s1 = "一行Java"; String s2 = new String("一行Java"); System.out.println(s1.equals(s2)); // true System.out.println(s1.equals("一行")); // false System.out.println(s1.equals(new Object())); // false }
示例输出
true
false
false
equalsIgnoreCase
将当前对象与指定对象比较,忽略大小写;
方法
javapublic boolean equalsIgnoreCase(String anotherString) {}
参数
- anotherString:要比较的字符串
返回
- true:相同
- false:不相同
示例
javapublic static void main(String[] args) { String s1 = "一行Java"; // 区分大小写比较 System.out.println(s1.equals("一行JAVA")); // false // 不区分大小写比较 System.out.println(s1.equalsIgnoreCase("一行JAVA")); // true }
示例输出
false
true
getBytes
将字符串编码为 byte 序列;
方法
javapublic byte[] getBytes() {} public byte[] getBytes(Charset charset) {} public byte[] getBytes(String charsetName) throws UnsupportedEncodingException {}
参数
- 无参:使用平台的默认字符集将字符串编码为 byte 序列
- charset:通过
Charset
指定字符集 - charsetName:通过编码名称指定字符集
返回
byte 数组
示例
javapublic static void main(String[] args) { try { String s1 = "一行Java"; // 根据系统默认的编码格式获取 byte 序列 System.out.println(s1.getBytes()); // [B@5fd0d5ae // GBK 的 Charset 对象 Charset gbkCharset = Charset.forName("GBK"); // 获取 UTF-8 的 byte 序列 System.out.println(s1.getBytes("UTF-8")); // [B@2d98a335 // 使用gbk获取 byte 序列,再用utf-8编码实例化对象,就会出现乱码情况 System.out.println(new String(s1.getBytes("GBK"), "UTF-8")); // һ��Java // 使用gbk获取字符集,同样使用gbk编码实例化对象,显示正常 System.out.println(new String(s1.getBytes(gbkCharset), gbkCharset)); // 一行Java } catch (UnsupportedEncodingException e) { e.printStackTrace(); } }
示例输出
[B@5fd0d5ae
[B@2d98a335
һ��Java
一行Java
getChars
将字符从当前字符串中复制到目标char数组
方法
javapublic void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) {}
参数
- srcBegin :当前字符串拷贝字符的起始下标
- srcEnd :当前字符串拷贝字符的结束下标
- dst:拷贝的目标数组
- dstBegin:目标数组起始下标
无返回值
示例
将
hello 一行Java
中第6个字符到第12字符的值拷贝到s2的数组中,拷贝下标从s2的第0个下标开始javapublic static void main(String[] args) { String s1 = "hello 一行Java"; char[] s2 = new char[6]; s1.getChars(6,12,s2,0); System.out.println(s2); // 一行Java }
示例输出
一行Java
hashCode
返回字符串的hash值
- 示例java示例输出
public static void main(String[] args) { String s1 = "hello 一行Java"; System.out.println(s1.hashCode()); // -1132908132 }
-1132908132
indexOf
获取指定字符在当前字符中第一次出现的位置
方法
javapublic int indexOf(int ch) {} public int indexOf(int ch, int fromIndex) {} public int indexOf(String str) {} public int indexOf(String str, int fromIndex) {}
参数说明
- ch:Unicode 编码的字符,如:a(97),b(98),c(99)...
- fromIndex:从当前字符集的那个下标开始找,默认是0
- str:指定的字符串
返回
首次出现的位置,
>=0
说明找到了,小于0就是没找到示例
查找
a
在当前字符串中的位置javapublic static void t13() { String s1 = "hello 一行Java"; // 查找Unicode 编码为97(a)第一次出现的位置 System.out.println(s1.indexOf(97)); // 9 // 从目标字符串的第10个索引开始,查找Unicode 编码为97(a)第一次出现的位置 System.out.println(s1.indexOf(97,10)); // 11 // 从头(下标为0)开始,查找a第一次出现的位置 System.out.println(s1.indexOf("a")); // 9 // 从目标字符串的第10个索引开始,查找a第一次出现的位置 System.out.println(s1.indexOf("a",10)); // 11 // 返回-1 说明没有找到 System.out.println(s1.indexOf("一航")); // -1 }
示例输出
9
11
9
11
-1
intern
如果字符常量池中已经包含一个等于此String对象的字符串,则返回常量池中字符串的引用,否则,将新的字符串放入常量池,并返回新字符串的引用;
方法
他是一个 native 方法;
javapublic native String intern();
无参
返回
常量池中对应字符串的地址;
示例1
javapublic static void t14_1() { String tmp = new String("一行"); String s5 = tmp + new String("爪哇"); String s6 = tmp + new String("爪哇"); System.out.println(s5 == s5.intern()); // true System.out.println(s6 == s6.intern()); // false System.out.println(s5 == s6.intern()); // true }
示例说明:
执行完1、2、3行代码,堆中分别创建了
tmp
、s5
、s6
三个对象,但是常量池中并没有一行爪哇
的常量;当执行完第4行的
s5.intern()
,会在常量池中加入一行爪哇
,同时将s5指向了常量池的地址,因此第四行的结果就是true第5行,执行
s6.intern()
返回的是s5同步到常量池的地址,与s6创建的地址不一样,所以这里返回的就是false第6行,执行
s6.intern()
返回的是s5同步到常量池的地址,与s5比较的时候,地址是一样,所以返回的就是true
示例2
javapublic static void t14_2() { String s3 = "一行爪哇"; String tmp = new String("一行"); String s5 = tmp + "爪哇"; String s6 = tmp + new String("爪哇"); System.out.println(s3 == s5); // false System.out.println(s3 == s6); // false System.out.println(s5 == s5.intern()); // false System.out.println(s6 == s6.intern()); // false System.out.println(s3 == s5.intern()); // true System.out.println(s3 == s6.intern()); // true String s7 = "一行" + "爪" + "哇"; System.out.println(s3 == s7); // true }
示例说明:
执行第1行之后,在常量池中就加入了
一行爪哇
执行第2、3、4行代码时,分别在堆中创建了
tmp
、s5
、s6
三个对象,s5
、s6
的值是指向的常量池一行爪哇
的地址,此时这里是会有两个对象;执行第5、6行代码时,由于
s5
、s6
是堆中地址,s3
是常量池地址,所以比较就都是false了执行第7、8行代码时,由于常量池中已经有
s3
创建的一行爪哇
,所以s5.intern()
、s6.intern()
返回的就是s3
的地址,与s5
、s6
的堆中比较,自然就不相等了,所以都返回了false;执行第9、10行代码时,由于
s5.intern()
、s6.intern()
返回的就是s3
的地址,所以这里与s3
比较自然就都是true了;执行第11、12行代码时,字符串的拼接,在编译的时候,会做优化,因此这里就直接得到了常量池
一行爪哇
的地址,因此s3
、s7
是同一个地址
总结
这个方法,理解起来稍微有点点麻烦,但是对于理解
String name = "一行爪哇"
、String name = new String("一行爪哇")
分别创建了几个对象这样的问题,比较的重要;String name = "一行爪哇"
常量池中有一行爪哇
是 0 个对象,没有就是 1 个对象String name = new String("一行爪哇")
;常量池中有一行爪哇
是 1 个对象,没有就是 2 个对象new String("一行爪哇").intern()
;常量池中有一行爪哇
是 1 个对象,没有就是 2 个对象
lastIndexOf
此方法和 indexOf 类似,只是这个方法是从后往前判断;获取指定字符在当前字符中第一次出现的位置;
方法
javapublic int lastIndexOf(int ch) {} public int lastIndexOf(int ch, int fromIndex) {} public int lastIndexOf(String str) {} public int lastIndexOf(String str, int fromIndex) {}
参数说明
- ch:Unicode 编码的字符,如:a(97),b(98),c(99)...
- fromIndex:从当前字符集的那个下标开始找,默认是0
- str:指定的字符串
返回
首次出现的位置,
>=0
说明找到了,小于0就是没找到示例
javapublic static void t15() { String s1 = "hello 一行Java"; System.out.println(s1.lastIndexOf(97)); // 11 System.out.println(s1.lastIndexOf(97, 10)); // 9 System.out.println(s1.lastIndexOf("l")); // 3 System.out.println(s1.lastIndexOf("l", 2)); // 2 System.out.println(s1.lastIndexOf("一航")); // -1 }
length
获取字符串的长度
- 示例java
String name = "一行Java"; System.out.println(name.length()); // 6
matches
判断字符串是否匹配正则表达式
方法
javapublic boolean matches(String regex) {}
参数
- regex:正则表达式
返回
- true:匹配成功
- false:匹配失败
示例
通过正则表达式,匹配电话号码!
javapublic static void main(String[] args) { // 电话号码的正则表达式 String regex = "^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$"; String phoneNum1 = "13888888888"; System.out.println(phoneNum1.matches(regex)); // true String phoneNum2 = "123456"; System.out.println(phoneNum2.matches(regex)); // false }
regionMatches
判断两个字符串部分区域是否相等(可忽略大小写)
方法
javapublic boolean regionMatches(int toffset, String other, int ooffset, int len) {} public boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) {}
参数
- ignoreCase:是否忽略大小写
- toffset:当前字符串的偏移下标
- other:目标字符串
- ooffset:目标字符串的偏移量
- len:匹配多长
返回
- true:匹配成功,相等
- false:匹配失败,不相等
示例
字符串1:
hello 一行Java,hello world
字符串2:
一行Java
或者一行JAVA
总字符串1的第8位开始,字符串2的第2位开始,比对4个字符(Java)
javapublic static void main(String[] args) { String s1 = "hello 一行Java,hello world"; System.out.println(s1.regionMatches(8, "一行Java", 2, 4)); // true System.out.println(s1.regionMatches(8, "一行JAVA", 2, 4)); // false 大小写不同 System.out.println(s1.regionMatches(true, 8, "一行JAVA", 2, 4)); // true 忽略了大写 }
replace
使用新的字符串替换当前字符串中的字符
方法
java// 替换指定字符 public String replace(char oldChar, char newChar) {} // 替换字符串 public String replace(CharSequence target, CharSequence replacement) {} // 根据正则,匹配替换所有 public String replaceAll(String regex, String replacement) {} // 根据正则,匹配替换第一个 public String replaceFirst(String regex, String replacement) {}
参数
- oldChar:旧字符
- newChar:新的字符
- target:旧的字符串
- replacement:新的字符串
- regex:匹配替换的正则表达式
返回
替换之后的字符串
示例
javapublic static void main(String[] args) { String s1 = "hello 一行Java,hello world"; String regex = "hello"; System.out.println(s1.replace('a','c')); // hello 一行Jcvc,hello world System.out.println(s1.replace("Java","JAVA")); // hello 一行JAVA,hello world System.out.println(s1.replaceAll(regex,"hi")); // hi 一行Java,hi world System.out.println(s1.replaceFirst(regex,"hi")); // hi 一行Java,hello world }
split
根据指定正则表达式,拆分字符串
方法
javapublic String[] split(String regex) {} public String[] split(String regex, int limit) {}
参数
- regex:表达式
- limit:拆分的份数
返回
拆分后的字符串数组
示例
使用
hello
拆分字符串javapublic static void main(String[] args) { String s1 = "hello 一行Java,hello world"; String[] ss = s1.split("hello"); // ["","一行Java,","world"] for (String s : ss) { System.out.println(s); } // 指定拆为2份 ss = s1.split("hello", 2); // ["","一行Java,hello world"] for (String s : ss) { System.out.println(s); } }
subSequence
字符序列截取,等价与 subString
方法
javapublic CharSequence subSequence(int beginIndex, int endIndex) {}
参数
- beginIndex:起始下标
- endIndex:结束下标
响应
截取后的字符序列
示例
javapublic static void main(String[] args) { String s1 = "hello 一行Java,hello world"; System.out.println(s1.subSequence(0, 12)); // hello 一行Java }
substring
字符串截取
方法
java// 指定起始下标,默认截取到最后 public String substring(int beginIndex) {} // 指定起始、结束下标 public String substring(int beginIndex, int endIndex) {}
参数
- beginIndex:起始下标
- endIndex:结束下标
返回
截取后的字符串
示例
javapublic static void main(String[] args) { String s1 = "hello 一行Java,hello world"; System.out.println(s1.substring(0, 12)); // hello 一行Java System.out.println(s1.substring(13)); // hello world }
toString
返回此对象本身,因为其本身就已经是一个字符串了。
- 示例
public static void main(String[] args) { String s1 = "一行Java"; System.out.println(s1.toString()); // 一行Java }
toCharArray
将此字符串转换为一个新的字符数组。
方法
javapublic char[] toCharArray() {
无参
返回
新的字符数组
示例
javapublic static void main(String[] args) { String s1 = "一行Java"; char[] chars = s1.toCharArray(); // 得到新的字符数组 }
toLowerCase
将字符串所有的字符转换为小写
方法
java// 使用默认语言环境的规则 public String toLowerCase() {} // 使用指定 Locale 规则 public String toLowerCase(Locale locale) {}
参数
- Locale:规则
返回
转为小写的字符串
示例
javapublic static void main(String[] args) { String s1 = "一行Java"; System.out.println(s1.toLowerCase()); // 一行java System.out.println(s1.toLowerCase(Locale.CHINA)); // 一行java }
toUpperCase
将字符串所有的字符转换为大写
方法
java// 使用默认语言环境的规则 public String toUpperCase() {} // 使用指定 Locale 规则 public String toUpperCase(Locale locale) {}
参数
- Locale:规则
返回
转为大写的字符串
示例
javapublic static void main(String[] args) { String s1 = "一行Java"; System.out.println(s1.toUpperCase()); // 一行JAVA System.out.println(s1.toUpperCase(Locale.CHINA)); // 一行JAVA }
trim
返回忽略开头空格和结尾的字符串副本。 注意,只有开头结尾会去掉,中间的不会
示例
javapublic static void main(String[] args) { String s1 = " 一行 Java "; System.out.println(s1.trim()); // 一行 Java }
valueOf
将不同数据类型的值转换为字符串
方法
java// 将 int 转换为字符串 public static String valueOf(int i) {} // 将 int 转换为字符串 String static String valueOf(long l) {} 将 float 转换为字符串 String static String valueOf(float f) {} 将 double 转换为字符串 String static String valueOf(double d) {} 将 char 转换为字符串 public static String valueOf(char c) {} 将 char 数组转换为字符串 String static String valueOf(char[] data) {} 将 char 数组截取并转换为字符串 public static String valueOf(char[] data, int offset, int count) {} 将 boolean 转换为字符串 public static String valueOf(boolean b) {} 将 对象 转换为字符串 public static String valueOf(Object b) {}
示例
javapublic static void main(String[] args) { System.out.println(String.valueOf(123)); // 123 System.out.println(String.valueOf('a')); // a System.out.println(String.valueOf(100000000000000L)); // 100000000000000 System.out.println(String.valueOf(200000000000000F)); // 2.00000001E14 System.out.println(String.valueOf(200000000000000D)); // 2.0E14 System.out.println(String.valueOf(true)); // true System.out.println(String.valueOf(new char[]{'a', 'b', 'c'})); // abc System.out.println(String.valueOf(new char[]{'a', 'b', 'c'}, 0, 2)); // ab System.out.println(String.valueOf(new Object())); // java.lang.Object@6acbcfc0 }
contains
判断当前字符串中,是否存在指定的字符序列
方法
javapublic boolean contains(CharSequence s) {}
参数
- s:要查找的字符序列
返回
- true:包含
- false:不包含
示例
javapublic static void main(String[] args) { String s1 = "一行Java"; System.out.println(s1.contains("Java")); // true System.out.println(s1.contains("JAVA")); // false }
isEmpty
判断字符串是否为空,包含包字符串
- 示例java
public static void t27() { String s1 = ""; System.out.println(s1.isEmpty()); // true String s2 = " "; System.out.println(s2.isEmpty()); // false }
isBlank
判断字符串是否为空,不包含包字符串
- 示例java
public static void t27() { String s1 = ""; System.out.println(s1.isBlank()); // true String s2 = " "; System.out.println(s2.isBlank()); // true }