String类
String代表字符串,它具有以下特点:
- 字符串是常量,创建之后不可改变
- 字符串字面值存储在字符串池中,可以共享
上述特点中的不可改变性主要体现在如果对一个字符串对象重新赋值,并不是去修改对象内部的字符串信息,而是先去字符串常量池查看是否存在新字符串,如果存在则返回地址;如果不存在则新创建一个字符串对象在字符串常量池中,然后返回地址。
例如下列代码:
String name = "hello";
name = "world";
假设字符串常量池默认为空,则一开始定义name的时候会在常量池新建一个字符串对象,内容为hello,然后name指向该对象,之后希望将name指向的对象修改为world,则在字符串常量池新建一个字符串对象,内容为world,然后将name指向world对象。
文章目录
- String类
- 两种创建方法比较
- equals()函数
- equalsIgnoreCase()函数
- compareTo()函数
- length()函数
- charAt(int index)函数
- contains(String str)函数
- toCharArray()函数
- indexOf(String str)函数
- lastIndexOf(String str)函数
- trim()函数
- toLowerCase()函数和toUpperCase()函数
- startsWith(String str)函数和endsWith(String str)函数
- replace(char oldChar, char newChar)函数
- split(String str)函数
- 测试代码
两种创建方法比较
Java中有两种创建字符串的方法,如下所示:
String str1 = "abc";
String str2 = new String("abc");
第一行创建字符串的方式(String str1 = “abc”),在创建字符串时,首先从字符串常量池中去查找是否已经存在“abc”这个字符串对象,如果存在的话,则直接返回常量池中的地址即可;如果不存在则新建一个字符串对象,内容为“abc”。
第二行创建字符串的方式,也是先从字符串常量池中去查找是否已经存在“abc”这个字符串对象,如果已经存在的话,则不需要在字符串常量池中新建对象,但是仍需要在堆中建立一个String对象,并赋值“abc”;如果字符串常量池中不存在,则新建一个到字符串常量池,之后在堆中也建立一个String对象,赋值“abc”,str2指向的是堆中的String对象。
故结合上述分析,第一种创建方法会创建0个或1个对象,第二种创建方法至少创建1个对象,也可能创建2个对象。
接下来通过一个例子来深入了解
package String;
public class demo01 {
public static void main(String[] args) {
String name = "hello"; // "hello" 存储在字符串常量池
String sex = "hello";
System.out.println(name == sex);
// 字符串的另一种创建方式,使用 new String 方式
String str1 = new String("java");
String str2 = new String("java");
System.out.println(str1 == str2);
}
}
输出结果为“true false”,因为name和sex都是指向字符串常量池中的同一个对象,而str1和str2是指向堆中的两个不同对象。
equals()函数
如果只想比较两个字符串的内容是否相同,则调用equals函数即可,Object函数中的equals函数只是比较两个对象的地址是否相同,String类中重写了该方法,改成了逐字符进行比较,如下所示:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
equalsIgnoreCase()函数
比较两个字符串的内容是否相同,且不考虑大小写。如果相同返回true,不想同返回false。
源码如下所示:
public boolean equalsIgnoreCase(String anotherString) {
return (this == anotherString) ? true
: (anotherString != null)
&& (anotherString.value.length == value.length)
&& regionMatches(true, 0, anotherString, 0, value.length);
}
compareTo()函数
返回值是整型,它是先比较对应字符的大小(ASCII码顺序),如果第一个字符和参数的第一个字符不等,结束比较,返回他们之间的长度差值,如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至比较的字符或被比较的字符有一方结束。
- 如果参数字符串等于此字符串,则返回值 0;
- 如果此字符串小于字符串参数,则返回一个小于 0 的值;
- 如果此字符串大于字符串参数,则返回一个大于 0 的值。
返回值计算方法:
如果第一个字符和参数的第一个字符不等,结束比较,返回第一个字符的ASCII码差值。
**如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至不等为止,返回该字符的ASCII码差值。 **
如果两个字符串不一样长,可对应字符又完全一样,则返回两个字符串的长度差值。
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
length()函数
返回字符串的长度,返回类型为int类型。
源码如下所示:
public int length() {
return value.length;
}
charAt(int index)函数
返回字符串index下标处的字符(从0开始),返回类型为char。
源码如下所示:
public char charAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index];
}
contains(String str)函数
判断字符串中是否包含str,如果包含,则返回true,反之则返回false。
源码如下所示:
public boolean contains(CharSequence s) {
return indexOf(s.toString()) > -1;
}
toCharArray()函数
该函数可以将字符串分解成一个字符数组,返回该字符串对应的字符数组。
源码如下所示:
public char[] toCharArray() {
// Cannot use Arrays.copyOf because of class initialization order issues
char result[] = new char[value.length];
System.arraycopy(value, 0, result, 0, value.length);
return result;
}
indexOf(String str)函数
该函数返回字符串str在原字符串中第一次出现的位置,如果不存在则返回-1。
源码如下所示:
public int indexOf(String str) {
return indexOf(str, 0);
}
// 返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。
public int indexOf(String str, int fromIndex) {
return indexOf(value, 0, value.length,
str.value, 0, str.value.length, fromIndex);
}
lastIndexOf(String str)函数
该函数返回字符串str在原字符串中最后一次出现的位置,如果不存在则返回-1.
源码如下所示:
public int lastIndexOf(String str) {
return lastIndexOf(str, value.length);
}
// 返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。
public int lastIndexOf(String str, int fromIndex) {
return lastIndexOf(value, 0, value.length,
str.value, 0, str.value.length, fromIndex);
}
trim()函数
返回字符串的副本,忽略前导空白和尾部空白。
源码如下所示:
public String trim() {
int len = value.length;
int st = 0;
char[] val = value; /* avoid getfield opcode */
while ((st < len) && (val[st] <= ' ')) {
st++;
}
while ((st < len) && (val[len - 1] <= ' ')) {
len--;
}
return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}
toLowerCase()函数和toUpperCase()函数
toLowerCase(): 使用默认语言环境的规则将此 String中的所有字符都转换为小写。
源码如下所示:
public String toLowerCase() {
return toLowerCase(Locale.getDefault());
}
toUpperCase(): 使用默认语言环境的规则将此 String中的所有字符都转换为大写。
源码如下所示:
public String toUpperCase() {
return toUpperCase(Locale.getDefault());
}
startsWith(String str)函数和endsWith(String str)函数
startWith(String str): 测试此字符串是否以指定的前缀开始。
startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始。
源码如下所示:
public boolean startsWith(String prefix) {
return startsWith(prefix, 0);
}
endsWith(String str): 测试此字符串是否以指定的后缀结束。
源码如下所示:
public boolean endsWith(String suffix) {
return startsWith(suffix, value.length - suffix.value.length);
}
replace(char oldChar, char newChar)函数
replace(char oldChar, char newChar)
返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。
源码如下所示:
public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
int len = value.length;
int i = -1;
char[] val = value; /* avoid getfield opcode */
while (++i < len) {
if (val[i] == oldChar) {
break;
}
}
if (i < len) {
char buf[] = new char[len];
for (int j = 0; j < i; j++) {
buf[j] = val[j];
}
while (i < len) {
char c = val[i];
buf[i] = (c == oldChar) ? newChar : c;
i++;
}
return new String(buf, true);
}
}
return this;
}
replace(CharSequence target, CharSequence replacement)
使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。
源码如下所示:
public String replace(CharSequence target, CharSequence replacement) {
return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(
this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
}
split(String str)函数
根据给定正则表达式的匹配拆分此字符串。
源码如下所示:
public String[] split(String regex) {
return split(regex, 0);
}
测试代码
package String;
import java.util.Arrays;
public class demo02 {
public static void main(String[] args) {
// 字符串方法的使用
// 1.length(): 返回字符串的长度
System.out.println("--------length---------");
String content = "java是世界上最好的语言";
System.out.println(content.length());
// 2.charAt(int index): 返回某个为止的字符
System.out.println("--------charAt---------");
System.out.println(content.charAt(content.length() - 1));
// 3.contains(String str): 判断是否包含某个字符串
System.out.println("--------contains---------");
System.out.println(content.contains("java"));
System.out.println(content.contains("php"));
// 4.toCharArray(): 返回字符串对应的数组
System.out.println("--------toCharArray---------");
char[] ch = content.toCharArray();
System.out.println(Arrays.toString(ch));
// 5.indexOf(String str): 返回字符串str首先出现的位置
System.out.println("--------indexOf---------");
System.out.println(content.indexOf("java"));
System.out.println(content.indexOf("java", 4));
System.out.println(content.indexOf("a"));
System.out.println(content.indexOf("php"));
// 6.lastIndexOf(String str): 返回字符串str最后出现的位置
System.out.println("--------lastIndexOf---------");
System.out.println(content.lastIndexOf("a"));
System.out.println(content.lastIndexOf("php"));
// 7.trim(): 去掉字符串前后的空格
System.out.println("--------trim---------");
String content2 = " hello world ";
System.out.println(content2.trim());
// 8.toUpperCase(): 把小写转换成大写(英文)
// 8.toLowerCase(): 把大写转换成小写(英文)
System.out.println("--------toLowerCase()---------");
System.out.println(content2.toLowerCase());
System.out.println("--------toUpperCase()---------");
System.out.println(content2.toUpperCase());
// 9.endWith(String str): 测试此字符串是否以指定的后缀结束。
// 9.startWith(String str): 测试此字符串是否以指定的前缀开始。
System.out.println("--------endWith---------");
String str1 = "java";
String str2 = "java----java";
System.out.println(str2.endsWith(str1));
System.out.println("--------startWith---------");
System.out.println(str2.startsWith(str1));
// 10.replace(char oldChar, char newChar)
// 用新的字符或字符串替换旧的字符或字符串
System.out.println("--------replace---------");
String newStr = "java".replace("a", "p");
System.out.println(newStr);
System.out.println(content.replace("java", "php"));
// 11.split(String str)
// 根据给定正则表达式的匹配拆分此字符串。
System.out.println("--------split---------");
String say = "java is the best programming,language in the world";
String[] arr = say.split(" ");
System.out.println(Arrays.toString(arr));
String[] arr1 = say.split("[ ,]+");
System.out.println(Arrays.toString(arr1));
// 12.equalsIgnoreCase()
System.out.println("--------equalsIgnoreCase---------");
String ss1 = "HELLO";
String ss2 = "hello";
System.out.println(ss1.equalsIgnoreCase(ss2));
// 13.compareTo()
// 按照字典顺序比较两个字符串的大小,从高位比到低位
String sss1 = "abc"; // a = 97
String sss2 = "xyz"; // x = 120
System.out.println(sss1.compareTo(sss2));
String sss3 = "axyz";
System.out.println(sss1.compareTo(sss3));
String sss4 = "abcxyz";
System.out.println(sss1.compareTo(sss4));
}
}