目录
一、String类的构造存储
在Java中String是字符串类型,使用String 变量名 = “字符串”;就可以定义一个字符串,在日常中比较常用的三种字符串定义方法。
public class Test {
public static void main(String[] args) {
//使用String的构造方法
String s1 = new String("Hello");
//直接赋值
String s2 = "World";
//使用数组
char[] chars = {'a','b','c','d'};
String s3 = new String(chars);
}
}
实际上String是由Java类库提供的一个预定义类,每个使用" "括起来的字符串都是String类的一个实例。String是引用类型,其内部并不存储字符串本身,实际上是通过一个value引用来存储字符串的。
public class Test {
public static void main(String[] args) {
String s1 = new String("Hello");
String s2 = new String("World");
}
}
在通过System.out.println("hello")中hello也是String类型可以使用.length来获取其长度。
public class Test {
public static void main(String[] args) {
System.out.println("hello".length());
}
}
二、字符串的操作方法
2.1、String对象地比较
2.1.1==比较是否引用同一个对象
在java中使用==可以比较基本类型中的值是否相等,但是对于引用类型==实际上比较的是引用的地址是否相同
public class Test {
public static void main(String[] args) {
String s1 = new String("hello");
String s2 = new String("world");
String s3 = new String("hello");
String s4 = s1;
System.out.println(s1 == s2);//false
System.out.println(s1 == s3);//false
System.out.println(s1 == s4);//true
System.out.println("hello".length());
}
}
2.1.2通过equals方法
在String类中重写了父类中Object中的equals方法,重写后equals方法我们可以比较两个字符串的值是否相同。
这个重写的equlas方法是按字典序逐个字符进行比较的,首先会先检测this和anObject是否为同一个对象,如果是dan直接返回true,如果不是会进行下面的三个比较;
检测anObject是否为String类型的对象,如果是则将anObject向下转型为String类型独享,比较this和anObject两个字符串的长度是否相同,相同的化就按照字典序从前到后对每个字符进行比较:
//1. 检测anObject是否为String类型的对象,如果是继续比较,否则返回false
if (anObject instanceof String) {
//将anObject向下转型为String类型对象
String anotherString = (String)anObject;
int n = value.length;
//2. this和anObject两个字符串的长度是否相同,是继续比较,否则返回false
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
//3. 按照字典序,从前往后逐个字符进行比较
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
2.1.3通过int compareTo(String s)方法
和equals 方法不同,compareTo返回的是int类型,java中compareTo方法类似于C/C++中的strcmp函数,其会按照字典次序比较如果出现不等的字符,会直接返回这两个字符的大小差值,如果前k个字符相等返回值为两个字符串长度的差值。
public class Test {
public static void main(String[] args) {
String s1 = new String("abc");
String s2 = new String("ac");
String s3 = new String("ad");
String s4 = new String("abcde");
String s5 = new String("abc");
System.out.println(s1.compareTo(s2));//-1
System.out.println(s1.compareTo(s3));//-2
System.out.println(s1.compareTo(s4));//-2
System.out.println(s1.compareTo(s5));//0
}
}
因此,在使用compareTo进行判断时可以这样使用
if (str1.compareTo(s2)==0){
}
当我们在不考虑大小写的区别时可以使用compareToIgnoreCase方法
String s1 = "abc";
String s2 = "ABC";
System.out.println(s1.compareToIgnoreCase(s2));//0
2.2字符串查找
2.2.1查找字符串中某个位置的字符
String str = "abcdefghijklmn";
System.out.println(str.charAt(1));//b
System.out.println(str.charAt(7));//h
使用char charAt(int index)方法可以返回指定位置上的字符,但当index为否数或者越界时会抛出IndexOutOfBoundsException异常。
2.2.2在给定字符串中查找指定字符或字符串的位置
String str = "abcdefghijklmn";
System.out.println(str.indexOf('a'));//0
System.out.println(str.indexOf("def"));//3
indexOf()方法将返回指定字符串在当前字符串中第一次出现的位置,通过该方法我们可以获取指定字符第一次出现的位置。也可以通过传入第二个参数来确定查找起点的位置
String str = "abcdabcdabcd";
System.out.println(str.indexOf('a',5));//8
lastIndexOf()也可以用来查找字符的第一次出现位置只不过与 indexOf()方法不同的是lastIndexOf()是从后向前查找的。
String str = "abcdabcdabcd";
System.out.println(str.lastIndexOf('a'));//8
2.2.3查找一个字符串中是否包含另一个字符串
String str = "abcdabcdabcd";
System.out.println(str.contains("abcd"));//true
System.out.println(str.contains("abcde"));//false
contains()方法可以用来检查当前字符串是否包含指定的子字符串。它的返回值是一个布尔值
2.3字符串转换
2.3.1数值和字符串之间的转换
String str1 = String.valueOf(1234);//整数转字符串
String str2 = String.valueOf(12.34);//浮点数转字符串
String str3 = String.valueOf(true);//布尔值转字符串
String str4 = String.valueOf(new Person("02",18));//对象转字符串
int a = Integer.parseInt(str1);//字符串转整数
double b = Double.parseDouble(str2);//字符串转浮点数
boolean c = Boolean.parseBoolean(str3);//字符串转布尔值
2.3.2大小写转化
String str = "aBcDeFgH";
System.out.println(str.toUpperCase());//ABCDEFGH 小写转大写
System.out.println(str.toLowerCase());//abcdefgh 大写转小写
2.3.3字符串与数组
String s = "hello";
char[] ch = s.toCharArray();// 字符串转数组
String s1 = new String(ch);//数组转字符串
2.3.4格式化
字符串的格式化则是对字符串内容进行修改和变形的一种常见处理方式。在许多场景中,特定的字符串格式是非常重要的,比如在数据交互、报表导出、日志记录等方面,都需要使用到字符串格式化。
String str = String.format("整数:%d,浮点数:%f,字符:%c,字符串:%s",10,10.2,'a',"hello");
System.out.println(string);//整数:10,浮点数:10.200000,字符:a,字符串:hello
2.4字符串拆分
使用split()可以将一个完整的字符串按照指定格式拆解划分为若干个字符串
String str = "hello world";
String[] strs = string1.split(" ");//将str按空格进行拆分
for (String s : strs) {
System.out.println(s);
}
也可以只对字符串的部分进行拆分
String str1 = "hello world hello world hello world";
String[] strs1 = string1.split(" ",3);//将str按空格进行拆分成三份
String str2 = "hello world hello world hello world";
String[] strs2 = string1.split(" ",6);//将str按空格进行拆分成六份
for (String s : strs1) {
System.out.println(s);
}
System.out.println("--------------------");
for (String s : strs2) {
System.out.println(s);
}
在遇到一些特殊字符如 "." , "*" , "+" , "|" , "\",等作为分割符可能五福正确切分,此时需要在其前面加上转义字符。
String str = "127.0.0.1";
String[] strings = str.split("\\.");
for (String s : strings) {
System.out.println(s);
}
2.5字符串截取
从一个完整的字符串之中截取出部分内容
String str = "hello world";
System.out.println(str.substring(5));//截取第五个字符后面的所有字符
substring()可以截取到从指定索引的结尾的字符,也可以指定截取其中部分内容
String str = "hello world";
System.out.println(str.substring(0,5));//截取下标为[0,5)的字符
2.6字符串拼接
与绝大数程序设计语言一样,Java中允许使用+号连接两个字符串
String s1 ="hello";
String s2 = " world";
System.out.println(s1+s2);//hello world
当将一个字符串与一个非字符串的值进行拼接时后者会被转换成字符串
2.7、字符串的不可变性
String是一种不可变对象,字符串中的内容是不可改变的,字符串不可被修改,在String类设计时就是不可改变的,String类的实现描述中就有其说明。
String类中的字符实际上时保存在内部维护的value数组中的。String类被final修饰表示该类不能被继承,value同样被value修饰,表明value自身的值不能改变,虽不能引用其它数组,但其引用空间的内容可以进行修改,在Java中所有涉及到可能修改字符串的内容的操作都是创建一个新的对象,改变的是新对象。
三、StringBuilder和StringBuffer
在实际操作过程中应尽量避免对String类型对象直接进行修改,在每次对String类型进行修改时都会构建一个新的String对象,不仅耗时而且浪费空间,效率低下。所以在修改字符串时可以创建一个StringBulid的对象然后通过addend方法来进行字符串的修改。
public class Test {
public static void main(String[] args) {
StringBuilder s1 = new StringBuilder();
String s2 = "hello";
System.out.println(s1.append("hello"));
System.out.println(s2);
StringBuilder str1 = s1;
String str2 = s2;
s2+=" world";
System.out.println(s1.append(" world"));
System.out.println(s2);
System.out.println("------------");
System.out.println(str1);
System.out.println(str2);
}
}
从上述代码中可以看出使用StringBuilder创建的字符串是可以进行修改的不会在创建临时变量
因此由于String的不可更改特性在修改时会产生较多的临时变量,Java为了方便字符串的修改,提供了StringBuilder和StringBuffer这两个类,这两个类之中的部分功能是相同的其中StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作。
String和StringBuilder之间是不能直接转换的,如果要想转换可以利用StringBuilder或者addend()方法。
StringBuilder s1 = new StringBuilder();
String s2 = "hello";
s1.append(s2);
StringBuilder s3 = new StringBuilder(s2);
而如果想将StringBuilder转为String类型,可以使用toString();
StringBuilder s1 = new StringBuilder("hello");
String s2 = s1.toString();