1.常用API
1.1. String 类
概述
java.lang.String
类代表字符串。
类 String
中包括用于检查各个字符串的方法,比如用于比较字符串,搜索字符串,提取子字符串以及创建具有翻译为大写或小写的所有字符的字符串的副本。
- 常量对象:字符串常量对象是用双引号括起的字符序列。 例如(
"abc"
)
特点
- 字符串不变:
String
是一个final
类,字符串的值在创建后不能被更改。 - 因为
String
对象是不可变的,所以它们可以被共享。 String
类其实是通过char
数组来保存字符串的。"abc"
等效于char[] data={ 'a' , 'b' , 'c' } 。
例如:
String str = "abc";
相当于:
char data[] = {
'a', 'b', 'c'};
String str = new String(data);
// String底层是靠字符数组实现的。
字符串常量池
JVM 为了提高性能和减少内存的开销,在实例化字符串的时候进行了一些优化:使用字符串常量池。
每当我们创建字符串常量时,JVM会首先检查字符串常量池,
- 如果该字符串已经存在常量池中,那么就直接返回常量池中的实例引用。
- 如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中。
由于String
字符串的不可变性我们可以十分肯定常量池中一定不存在两个相同的字符串。
1.1.1.常用方法
构造
// 无参构造
String str = new String();
// 通过字符数组构造
char chars[] = {
'a', 'b', 'c'};
String str2 = new String(chars);
// 通过字节数组构造
byte bytes[] = {
97, 98, 99 };
String str3 = new String(bytes);
判断方法
public boolean equals (Object anObject)
:将此字符串与指定对象进行比较。public boolean equalsIgnoreCase (String anotherString)
:将此字符串与指定对象进行比较,忽略大小写。
获取功能的方法
public int length ()
:返回此字符串的长度。public String concat (String str)
:将指定的字符串连接到该字符串的末尾。public char charAt (int index)
:返回指定索引处的 char值。public int indexOf (String str)
:返回指定子字符串第一次出现在该字符串内的索引。public String substring (int beginIndex)
:返回一个子字符串,从beginIndex
开始截取字符串到字符串结尾。(包含 index )public String substring (int beginIndex, int endIndex)
:返回一个子字符串,从beginIndex
到endIndex
截取字符串。含beginIndex
,不含endIndex
。(左闭右开)
//简单示例使用
String s = "helloworld";
System.out.println(s.substring(1));// 结果"elloworld"
转换功能的方法
public char[] toCharArray ()
:将此字符串转换为新的字符数组public byte[] getBytes ()
:使用平台的默认字符集将该String
编码转换为新的字节数组。public String replace (CharSequence target, CharSequence replacement)
:将与target
匹配的字符串使用replacement
字符串替换。
String str = "study Java";
String replace = str.replace("st", "ST");
System.out.println(replace); // STudy Java
分隔功能的方法
public String[] split(String regex)
:将此字符串按照给定的regex
(规则)拆分为字符串数组
//创建字符串对象
String s = "aa|bb|cc";
String[] strArray = s.split("|"); // ["aa","bb","cc"]
1.1.2.字符串比较
String str1 = "aaa";
String str2 = "aaa";
System.out.println(str1 == str2);// true 因为String有常量池
String str3 = new String("aaa");
String str4 = new String("aaa");
System.out.println(str3 == str4);// false 可以看出用new的方式是生成不同的对象,比较堆上的
String s0="helloworld";
String s1="helloworld";
String s2="hello"+"world";
System.out.println(s0==s1); //true 可以看出s0跟s1是指向同一个对象
System.out.println(s0==s2); //true 可以看出s0跟s2是指向同一个对象
String st0="helloworld";
String st1=new String("helloworld");
String st2="hello" + new String("world");
System.out.println( st0==st1 ); //false 用new String() 创建的字符串不是常量,不能在编译期就确定
System.out.println( st0==st2 ); //false st2地址存在堆中,不可能相同
System.out.println( st1==st2 ); //false
String stri1="abc";
String stri2="def";
String stri3=stri1+stri2;
System.out.println(stri3=="abcdef"); //false 变量相+是在的堆内存中创建
String strin0 = "a1";
String strin1 = "a" + 1; //这种不是变量,是常量
System.out.println((strin0 == strin1)); //result = true
String strin2 = "atrue";
String strin3= "a" + "true";
System.out.println((strin2 == strin3)); //result = true
String strin4 = "a3.4";
String strin5 = "a" + 3.4;
System.out.println((strin4 == strin5)); //result = true
String string0 = "ab";
String string1 = "b";
String string2 = "a" + string1;
System.out.println((string0 == string2)); //result = false 在字符串的"+"连接中,有字符串引用存在,而引用的值在程序编译期是无法确定的
String test="javalanguagespecification";
String test2="java";
String test3="language";
String test4="specification";
System.out.println(test == "java" + "language" + "specification"); //true 字符串字面量拼接操作是在Java编译器编译期间就执行了
System.out.println(test == test2 + test3 + test4); //false 字符串引用的"+"运算是在Java运行期间执行的
String ss0 = "ab";
final String ss1 = "b";
String ss2 = "a" + ss1;
System.out.println((ss0 == ss2)); //result = true 对于final修饰的变量,它在编译时被解析为常量值的一个本地拷贝存储到自己的常量池中或嵌入到它的字节码流中。所以此时的"a" + s1和"a" + "b"效果是一样的
String ss10 = "ab";
final String ss11 = getS1();
String ss12 = "a" + ss11;
System.out.println((ss10 == ss12)); //result = false 这里面虽然将s1用final修饰了,但是由于其赋值是通过方法调用返回的,那么它的值只能在运行期间确定
public static String getS1(){