我们之前在C语言中已经涉及到字符串了,但是在C语言中要表示字符串只能使用字符数组或者字符指针,可以使用标准库提供的字符串系列函数完成大部分操作,但是这种将数据和操作数据的方法分离开的方式不符合面向对象的思想,而字符串应用又非常广泛,因此Java语言专门提供了String类。
而且在现在的开发和校招笔试中,String类更是举足轻重,所以今天就让我们看看String类。
String类中提供的构造方式非常多,常用的就有以下三种:
public static void main(String[] args) {
//使用常量字符串构造
String s1 = "hello world";
System.out.println(s1);
//直接newString对象
String s2 = new String("hello world");
System.out.println(s2);
//使用字符数组进行构造
char[] array = {'h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd'};
String s3 = new String(array);
System.out.println(s3);
}
注意:
1.String是引用类型,内部并不存储字符串本身,在String类的实现源码中,String类的实例变量如下:
我们可以看出:String主要有两个成员:value[ ], hash.
hash:在 Java 中,
String
类中的hash
是通过hashCode()
方法计算的,而hashCode()
方法是根据字符串的内容计算得到的。当你调用hashCode()
方法时,实际上是根据字符串的字符内容来计算一个哈希码值。一般hash默认为0value[ ]:在 Java 中,
String
类中的value[]
是一个字符数组,它存储了字符串的字符内容。每个String
对象都有一个value[]
数组来存储字符串的字符,这个数组是private final char[]
类型的。
public static void main(String[] args) {
//s1和s2引用的是不同的对象 s1和s3引用的是不同对象
String s1 = new String("hello");
String s2 = new String("world");
String s3 = s1;
String s4 = "";//表明指向的对象是空的
String s5 = null;//表明不指向任何对象
System.out.println(s1.length());//获取字符串的长度-输出5
//isEmpyt():检查字符串是否是空,如果是空返回true,不是空返回false
System.out.println(s1.isEmpty());//false
System.out.println(s4.isEmpty());//true
System.out.println(s5.isEmpty());//空指针异常
}
2.在Java中,用""引起来的也是String类型的对象。
字符串的比较也是常见的操作之一,比如:字符串排序。Java中共提供了4种方式:
1.==比较是否引用的是同一对象。
注意:对于内置类型(int等基础类型等),==比较的是变量中的值;对于引用类型,==比较的是引用中的地址。
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = 10;
//对于基本类型变量,==比较的是两个变量中存储的值是否相同
System.out.println(a == b);//false
System.out.println(a == c);//true
//对于引用类型变量,==比较的是两个引用变量引用的是否为同一个对象
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
}
2.boolean equals(Object anObject)方法:按照字典序比较
字典序:字符大小的顺序
String类重写了父类Object中的equals方法,Object中equals默认按照==比较,String重写equals方法后,按照如下规则进行比较:比如s1.equals(s2)
public boolean equals(Object anObject) {
// 1. 先检测this 和 anObject 是否为同一个对象比较,如果是返回true
if (this == anObject) {
return true;
}
// 2. 检测anObject是否为String类型的对象,如果是继续比较,否则返回false
if (anObject instanceof String) {
// 将anObject向下转型为String类型对象
String anotherString = (String)anObject;
int n = value.length;
// 3. this和anObject两个字符串的长度是否相同,是继续比较,否则返回false
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
// 4. 按照字典序,从前往后逐个字符进行比较
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
举个使用的例子:
public static void main(String[] args) {
String s1 = new String("hello");
String s2 = new String("hello");
String s3 = new String("Hello");
//s1,s2,s3引用的是三个不同的对象,因此==比较全部为false
System.out.println(s1 == s2);//false
System.out.println(s1 == s3);//false
//equals比较:String对象中的逐个字符
//虽然s1和s2引用的是不同的对象,但是两个对象中放置的内容相同
//s1和s3引用的是不同的对象,而且两个对象中的内容也不同
System.out.println(s1.equals(s2));//true
System.out.println(s1.equals(s3));//false
}
3.int compareTo(String s)方法:按照字典序进行比较
与equals不同的是,equals返回的是boolean类型,而compareTo返回的是int类型。具体比较方式:
1.先按字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值
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));//不同输出字符差值-1
System.out.println(s1.compareTo(s3));//相同输出0
System.out.println(s1.compareTo(s4));//前k个字符完全相同,返回长度差值-3
}
4.int compareTolgnoreCase(String str)方法:与compareTo方式相同,但是忽略大小写比较
字符串查找也是字符串中非常常见的操作,String类提供常用查找方法:
方法 | 功能 |
char charAt(int index) | 返回index位置上的字符,如果index负数或者越界,抛出 IndexOutOfBoundsException异常 |
int indexOf(int ch) | 返回ch第一次出现的位置,没有则返回-1 |
int indexOf(int ch, int fromIndex) | 从fromIndex位置开始找ch第一次出现的位置 |
int IndexOf(String str) | 返回str第一次出现的位置,没有则返回-1 |
int IndexOf(String str, int fromIndex) | 从fromIndex位置开始找str第一次出现的位置,没有返回-1 |
int lastIndexOf(int ch) | 从后往前找,返回ch第一次出现的位置,没有返回-1 |
int lastIndexOf(String str) | 从后往前找,返回str第一次出现的位置,没有返回-1 |
int lastIndexOf(int ch, int fromIndex) | 从fromIndex位置开始从后往前找ch第一次出现的位置,没有返回-1 |
int lastIndexOf(String str,int fromIndex) | 从fromIndex位置开始从后往前找str第一次出现的位置,没有返回-1 |
下面以一段字符串来举个例子:
public static void main(String[] args) {
String s = "aaabbbcccaaabbbccc";
System.out.println(s.charAt(3));//'b
System.out.println(s.indexOf('d'));//-1
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.数值和字符串的转化
public static void main(String[] args) {
//数值转字符串
String s1 = String.valueOf(1234);
String s2 = String.valueOf(12.34);
String s3 = String.valueOf(true);
String s4 = String.valueOf(new Student("zhangsan", 18));
//打印
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
System.out.println(s4);//打印的是对象名@哈希码
System.out.println("======================");
//字符串转数字
//注意:Integer,Double等是Java的包装类型,这个后面会讲
int data1 = Integer.parseInt("1234");
double data2 = Double.parseDouble("12.34");
System.out.println(data1);
System.out.println(data2);
}
2.大小写转换
public static void main(String[] args) {
String s1 = "hello";
String s2 = "HELLO";
//注意:不是在原来的基础上转变,转变之后是一个新的对象
//小写转大写
System.out.println(s1.toUpperCase());//HELLO
System.out.println(s2.toLowerCase());//hello
}
3.字符串转数组
public static void main(String[] args) {
String s = "hello";
//字符串转数组
char[] ch = s.toCharArray();
for(int i=0; i
4.格式化
public static void main(String[] args) {
String s = String.format("%d-%d-%d", 2019, 9, 14);
System.out.println(s);
}
使用一个新的字符串替换掉已有字符串的数据,可用的方法如下:
方法 | 功能 |
String replaceAll(String regex, String replacement) | 替换掉所有的指定内容 |
String replaceFirst(String regex, String replacement) | 替换首个内容 |
String replace(String target, String replacement) | 将所有目标字符串替换为指定字符串 |
String replace(char oldChar, char newChar) | 将所有旧字符替换为新字符 |
注意事项:由于字符串是不可变对象,替换不更改当前字符串,而是产生一个新的字符串