1.String的常用方法
1.1 字符串构造
String的常用构造方法为以下三种
public class test57 {
public static void main(String[] args) {
//第一种
String s1 = "hello";
System.out.println(s1);
//第二种
String s2 = new String ("hello");
System.out.println(s2);
//第三种
char[] array = {'h','e','l','l','o'};
String s3 = new String (array);
System.out.println(s3);
}
}
hello
hello
hello
【注意】
1.String是引用类型,内部并不存储字符串本身。
2.在java中“”引起来的也是String类型对象
System.out.println("hello".length());
1.2 String对象的比较
java中字符串的排序
1. ==比较是否引用同一个对象
注意:对于内置类型,==比较的是变量中的值;对于引用类型==比较的是引用中的地址,即是否为同一个对象。
public class test61 {
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 world");
String s2 = new String("hello");
String s3 = new String("hello world");
String s4 = s3;
System.out.println(s1 == s2);//false
System.out.println(s1 == s3);//false
System.out.println(s4 == s3);//true
}
}
2.boolean equals(Object anObject)方法:按照字典序比较
字典序:字符的大小顺序
public boolean equals(Object anObject) {
if (this == anObject) { // 如果是同一个对象的引用,则认为是相等的
return true;
}
if (anObject instanceof String) { // 确保传入的对象是 String 类型的
String anotherString = (String) anObject;
int n = value.length; // 假设 value 是 String 类内部用于存储字符的数组
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; // 如果不是 String 类型的对象,或者长度不同,则认为不相等
}
以上是伪代码并不是实际的实现方法。
3. int compareTo(String s)方法:按照字典序进行比较
与equals进行比较,equals返回的是boolean类型,而compareTo返回的是int类型,具体比较如下:
1.先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值
2.如果前k个字符相等(k为两个字符长度最小值),返回两个字符串长度差值
public class HelloWorld{
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));//前几个相同,输出长度字符差值为-3
}
}
4.int compareToIgnoreCase(String str)方法:与compareTo方式相同,但是忽略大小写比较
public class HelloWorld{
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");
String s5 = new String ("ABCD");
System.out.println(s1.compareToIgnoreCase(s2)); //-1
System.out.println(s1.compareToIgnoreCase(s3));//0
System.out.println(s1.compareToIgnoreCase(s4));//-3
System.out.println(s1.compareToIgnoreCase(s5));//-1
}
}
1.3 字符串查找
String类提供的常用查找的方法:
public class test61 {
public static void main(String[] args) {
String s = "aabbbccdd";
//返回3位置上的字符,如果数字为负数或者越界,抛出IndexOutOfBoundsException异常,结果为:b
System.out.println(s.charAt(3));
//返回c第一次出现的位置,没有返回-1,结果为:5
System.out.println(s.indexOf('c'));
//从3位置开始找c第一次出现的位置,没有返回-1,结果为:6
System.out.println(s.indexOf('c',6));
//返回ccc第一次出现的位置,没有返回-1,结果为:-1
System.out.println(s.indexOf("ccc"));
//从3位置开始找第一次出现bb的位置,没有返回-1,结果为:3
System.out.println(s.indexOf("bb",3));
//从后往前找返回a第一次出现的位置,没有返回-1,结果为:1
System.out.println(s.lastIndexOf("a"));
//从5位置开始找,从后往前找第一次出现c的位置,结果为:5
System.out.println(s.lastIndexOf("c",5));
//从后往前找,返回bbb第一次出现的位置,没有返回-1,结果为:2
System.out.println(s.lastIndexOf("bbb",8));
//从3位置往前找,返回cc第一次出现的位置,没有返回-1,结构为:-1
System.out.println(s.lastIndexOf("cc",3));
}
}
1.4 转化
1. 数值和字符串转化
public class test62 {
public static void main(String[] args) {
//数字转字符串
String s1 = String.valueOf(12345);
String s2 = String.valueOf(12.42);
String s3 = String.valueOf(true);
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
System.out.println("====");
//字符串转数字
int data1 = Integer.parseInt("1234");
double date2 = Double.parseDouble("12.34");
System.out.println(data1);
System.out.println(date2);
}
}
//结果
//12345
//12.42
//true
//====
//1234
//12.34
2.大小写转换
public class test64 {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "HELLO";
String s3 = "hello%#";
System.out.println(s1.toUpperCase());
System.out.println(s2.toLowerCase());
System.out.println(s3.toUpperCase());
}
}
//HELLO
//hello
// HELLO%#
注意:这里只转换字母
3.字符串转数组
public class test63 {
public static void main(String[] args) {
String s = "hello";
char[] ch = s.toCharArray();
for (int i = 0; i < ch.length; i++) {
System.out.println(ch[i]);
}
String s2 = new String (ch);
System.out.println(s2);
}
}
//结果
//h
//e
//l
//l
//o
//hello
4.格式化
public class test65 {
public static void main(String[] args) {
String s = String.format("%d-%d-%d",2019,9,14);
System.out.println(s);
}
}
//结果
//2019-9-14
1.5 字符串替换
使用指定的字符串替换已有的字符串,可使用以下方法
public class test66 {
public static void main(String[] args) {
String s1 = "hello";
System.out.println(s1.replaceAll("l","-"));
System.out.println(s1.replaceFirst("l","-"));
System.out.println(s1.replace("l","a"));
}
}
//结果
//he--o
//he-lo
//heaao
注意事项:由于字符串是不可变对象,替换不修改当前字符串而是产生一个新的字符串。
1.6 字符串拆分
将一个完整的字符串按照指定的分割符划分为若干个子字符串
public class test67 {
public static void main(String[] args) {
String s1 = "hello world hello everyone";
String[] s2 = s1.split(" ");
for(String s3:s2){
System.out.println(s3);
}
}
}
//结果
//hello
//world
//hello
//everyone
public class test67 {
public static void main(String[] args) {
String s1 = "hello world hello everyone";
String[] s2 = s1.split(" ",3);
for(String s3:s2){
System.out.println(s3);
}
}
}
//结果
//hello
//world
//hello everyone
注意事项:
1.字符“|”,“*”,“+”都得加上转义字符,前面加上“\\”.
2.而如果是“\”,那么就得写成“\\\\”.
3.如果一个字符串中有多个分隔符,可以使用“|”作为连字符
代码示例:多次拆分
public class test68 {
public static void main(String[] args) {
String s1 = "1982.3.15" ;
String[] s2 = s1.split("\\.");
for(String s3:s2){
System.out.println(s3);
}
}
}
//结果
//1982
//3
//15
public static void main(String[] args) {
String s1 = "hello=world&hi=19";
String[] s2 = s1.split("&");
for (int i = 0; i < s2.length; i++) {
String[] s3 = s2[i].split("=");
System.out.println(s3[0]+"="+s3[1]);
}
}
}
//结果
// hello=world
//hi=19
1.7 字符串截取
从一个完整的字符串之中截取部分内容,可用方法如下:
public class test69 {
public static void main(String[] args) {
String str = "hello";
System.out.println(str.substring(4));
System.out.println(str.substring(0,5));
}
}
//结果
// o
//hello
注意事项:
1.索引从0开始
2.注意前闭后开区间,substring(0,5)表示包含0号下标的字符,不包含5号下标
1.8 其他操作方法
1.String trim():去掉字符串左右空格,保留中间空格
public class test69 {
public static void main(String[] args) {
String str = " hello world ";
System.out.println("["+str+"]");
System.out.println("["+str.trim()+"]");
// System.out.println(str.substring(4));
// System.out.println(str.substring(0,5));
}
}
//结果
// [ hello world ]
//[hello world]
1.9 字符串的不可变性
String是一种不可变对象,字符串中的内容是不可改变。字符串不可被修改,是因为:
1.String类在设计时就是不可改变的,String类实现描述中已经说明了
String类中的字符实际保存在内部维护的value字符数组中,改图还可以看出:
1.String类被final修饰,表明该类不能被继承
2.value 被fianl修饰,表明value自身的值不能改变,即不能引用其他字符数组,但是其引用空间中的内容可以修改。
2. 所涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象。网上很多人说,字符串不可变是因为其内部保存字符的数组被final修饰了,因此不能改变。这种说法是错误的,不是因为String类自身,或其内部value被final修饰。final修饰类表明该类不能被继承,fianl修饰引用类型表明该引用变量不能引用其他对象,但是引用对象中的内容是可以修改的。
import java.util.Arrays;
public class test70 {
public static void main(String[] args) {
final int array[] = {1, 2, 3, 4};
array[0] = 100;
System.out.println(Arrays.toString(array));
}
}
//[100, 2, 3, 4]
3.为什么String要设计成不可变的?
1.为了方便实现字符串对象池
2.不可变对象是线程安全
3.不可变对象方便缓存
那想要修改字符串中的内容,改如何实现?
2 字符串修改
2.1直接修改
注意:尽量避免直接对String类型对象进行修改,因为String类是不能修改的,所有的修改都会创建新对象,效率非常地下。
public static void main(String[] args) {
String s = "hello";
s+="world";
System.out.println(s);
}
// helloworld
这种效率极低,中间创建了许多变量,因此避免直接对String直接修改,如果要修改可以使用StringBuilder和StringBuffer类。
2.2 使用StringBuilder和StringBuffer进行修改
2.2.1 StringBuilder的介绍
由于String的不可更改性,为了方便字符串的修改,在java中提供StringBuilder和StringBuffer类。这两个类大部分功能是相同的,这里介绍StringBuilder常用的方法
public static void main(String[] args) {
StringBuilder s1 = new StringBuilder("hello");
StringBuilder s2 = s1;
s1.append(" ");//hello
s1.append("world");//hello world
s1.append(123);//hello world123
System.out.println(s1);//hello world123
System.out.println(s1 == s2);//true
System.out.println(s1.charAt(0));//h
System.out.println(s1.capacity());//21 获取底层数组的总大小
s1.setCharAt(0,'H');//设置任意位置的字符Hello world123
s1.insert(0,"hello world!!!");//hello world!!!Hello world123
System.out.println(s1);
System.out.println(s1.indexOf("Hello"));// 14 获取Hello第一次出现的位置(空隔也算)
System.out.println(s1.lastIndexOf("o"));//21 获取0第一次出现的位置(空隔也算)
s1.deleteCharAt(1);//hllo world!!!Hello world123 删除位置1上的字符
s1.delete(3,6);//hllorld!!!Hello world123 删除位置3到6上的字符
String s3 = s1.substring(0,5);//hllor 截取[0,5)区间中的字符以String的方式返回
System.out.println(s3);
s1.reverse(); //321dlrow olleH!!!dlrollh 字符串逆序
}
从上面的例子可以看出:String和StringBuilder 最大的区别在于String的内容·无法修改,而StringBuilder的内容可以修改。
注意:String 和StringBuilder类不能直接转换。如果要装换可以采用以下原则:
1. 利用StringBuilder的构造方法或者append()方法,将 String变为StringBuilder。
String str = "Hello, World!";
StringBuilder sb = new StringBuilder(str);
String str = "Hello, ";
StringBuilder sb = new StringBuilder();
sb.append(str);
sb.append("World!");
2.调用toString()方法,使StringBuilder变为String
StringBuilder sb = new StringBuilder("Hello, ");
sb.append("World!");
String str = sb.toString();
System.out.println(str); // 输出 "Hello, World!"
2.1.2 StringBuuffer的介绍
大部分的方法是一样的
public class test71 {
public static void main(String[] args) {
StringBuffer s1 = new StringBuffer("hello");
s1.append(" ");//hello
s1.append("world");//hello world
s1.append(123);//hello world123
System.out.println(s1);//hello world123
System.out.println(s1.charAt(0));//h
System.out.println(s1.capacity());//21 获取底层数组的总大小
s1.setCharAt(0,'H');//设置任意位置的字符Hello world123
s1.insert(0,"hello world!!!");//hello world!!!Hello world123
System.out.println(s1);
System.out.println(s1.indexOf("Hello"));// 14 获取Hello第一次出现的位置(空隔也算)
System.out.println(s1.lastIndexOf("o"));//21 获取0第一次出现的位置(空隔也算)
s1.deleteCharAt(1);//hllo world!!!Hello world123 删除位置1上的字符
s1.delete(3,6);//hllorld!!!Hello world123 删除位置3到6上的字符
String s3 = s1.substring(0,5);//hllor 截取[0,5)区间中的字符以String的方式返回
System.out.println(s3);
System.out.println( s1.reverse()); //321dlrow olleH!!!dlrollh 字符串逆序
}
}