Bootstrap

Java进阶__String类

在 Java 中,String类用于表示一串字符序列。String是一个对象类,又被设计为不可变类(immutable class)。String类在 Java 中提供了多种处理字符串的方法,还对性能进行了优化。

1. 特点

  • 不可变性String对象是不可变的,意味着一旦一个String对象被创建,它的值不能被更改(在string类里进行了私有private和final处理)。如果我们对一个String对象进行修改操作(如拼接、替换等),实际上是创建了一个新的String对象,而原有的String对象不会被改变。

  • 使用字面量存储:Java中的字符串字面量(即通过双引号创建的字符串)会自动保存在字符串池中(String Pool)。这样可以节省内存空间,避免重复创建相同的字符串对象。

  • 实现CharSequence接口String类实现了CharSequence接口,允许它与其他类一起工作,提供了一些与字符序列相关的方法。

  • 线程安全:由于String是不可变的,因此它是线程安全的。不同的线程可以安全地共享同一个String对象。

2. 字符串处理

2.1 创建字符串
2.1.1 双引号直接创建
//使用双引号直接创建字符串字面量:
String str = "Hello, World!";
//字符串字面量会被存储在字符串池(String Pool)中。
//如果另一个地方创建了相同的字符串,Java会重用字符串池中的对象,而不是创建新的对象。
2.1.2 使用new关键字
String str = new String("Hello, World!");
// 使用`new`关键字时,字符串对象会被创建在堆内存中,而不是字符串池中。
// 虽然这样可以创建新的`String`对象,但通常不推荐使用这种方式,因为它不利用字符串池的优化。
2.2 获取字符串长度length()
String str = "Hello";
int length = str.length(); // 返回字符串的长度
System.out.println(length); // 输出 5
2.3 字符串拼接
  • 使用+操作符

    String str1 = "Hello";
    String str2 = "World";
    String result = str1 + " " + str2; // 拼接两个字符串
    System.out.println(result); // 输出 "Hello World"
    
  • 使用concat()方法

    String str1 = "Hello";
    String str2 = "World";
    String result = str1.concat(" ").concat(str2); // 拼接字符串
    System.out.println(result); // 输出 "Hello World"
    
  • 使用StringBuilder(推荐)

    String str1 = "Hello";
    String str2 = "World";
    StringBuilder sb = new StringBuilder(str1);
    sb.append(" ").append(str2);
    System.out.println(sb.toString()); // 输出 "Hello World"
    

    StringBuilder类是专门设计用来高效拼接字符串的类,适合用于拼接大量字符串的场景。

2.4 字符串比较
  • 使用equals()方法:比较两个字符串的内容是否相同。

    String str1 = "Hello";
    String str2 = "Hello";
    boolean isEqual = str1.equals(str2); // 返回 true
    
  • 使用equalsIgnoreCase()方法:忽略大小写地比较字符串。

    String str1 = "hello";
    String str2 = "HELLO";
    boolean isEqual = str1.equalsIgnoreCase(str2); // 返回 true
    
  • 使用compareTo()方法:比较两个字符串字符的 Unicode 值。

    String str1 = "apple";
    String str2 = "banana";
    int result = str1.compareTo(str2); // 返回负数,"apple"<"banana"
    //若返回0,表示 str1 == str2
    //若返回正值,表示 str1 > str2
    
2.5 子串提取substring(7,12)不包12
  • 使用substring()方法:提取子字符串。
    String str = "Hello, World!";
    String substr = str.substring(7, 12); // 从索引7到索引12(不包括12)
    System.out.println(substr); // 输出 "World"
    
2.6 字符串查找
  • 使用indexOf()方法:返回指定字符或子字符串首次出现的位置。

    String str = "Hello, World!";
    int index = str.indexOf("World"); // 返回 7
    System.out.println(index);
    
  • 使用lastIndexOf()方法:返回指定字符或子字符串最后一次出现的位置。

    String str = "Hello, World!";
    int index = str.lastIndexOf("l"); // 返回 10
    System.out.println(index);
    
2.7 字符串替换replace(待替换字符串,新字符串)
  • 使用replace()方法:替换字符串中的字符或子字符串。
    String str = "Hello, World!";
    String newStr = str.replace("World", "Java");
    System.out.println(newStr); // 输出 "Hello, Java!"
    
2.8 字符串分割split(自定义分隔符)
  • 使用split()方法:将字符串按照指定的分隔符分割成多个子字符串。

    String str = "apple,banana,orange";
    String[] fruits = str.split(",");
    for (String fruit : fruits) {
        System.out.println(fruit);
    }
    

    输出

    apple
    banana
    orange
    
2.9 去除空白字符trim()
  • 使用trim()方法:去除字符串前后的空白字符。
    String str = "   Hello, World!   ";
    String trimmed = str.trim();
    System.out.println(trimmed); // 输出 "Hello, World!"
    
2.10 转换大toUpperCase()小toLowerCase()写
  • 使用toUpperCase()方法:将字符串转换为大写。

    String str = "hello";
    String upperStr = str.toUpperCase();
    System.out.println(upperStr); // 输出 "HELLO"
    
  • 使用toLowerCase()方法:将字符串转换为小写。

    String str = "HELLO";
    String lowerStr = str.toLowerCase();
    System.out.println(lowerStr); // 输出 "hello"
    

3. 字符串池(String Pool)

在 Java 中,字符串字面量(如 "abc")会被存储在一个叫做字符串池(String Pool)的特殊内存区域。每次遇到相同的字符串字面量时,Java 会直接返回该池中已存在的字符串对象,而不是创建新的字符串对象。这种机制提高了内存利用率,减少了重复创建字符串对象的开销。

例如:

String str1 = "Hello";
String str2 = "Hello";
System.out.println(str1 == str2); // 输出 true,指向同一个字符串池中的对象

然而,通过 new 关键字创建的字符串不会使用字符串池:

String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1 == str2); // 输出 false,指向不同的对象

此外还有class文件常量池,运行常量池

4. 对数组的一些操作

在 Java 中,String 类本身是不可变的(immutable),即它一旦创建后不能被修改。因此,String 类并不直接支持对字符数组的拷贝、插入或删除操作。但我们可以通过使用 String 构造函数、StringBuilderStringBuffer 等类来间接实现这些操作。

  • 拷贝操作:可以通过 String 构造函数(new String())或 System.arraycopy() 来实现。
  • 插入操作:使用 StringBuilder.insert() 方法来在指定位置插入字符串。
  • 删除操作:使用 StringBuilder.delete()deleteCharAt() 来删除指定位置的字符或子串。
  • 替换操作:使用 String.replace()StringBuilder.replace() 来替换指定的字符或子串。
4.1拷贝
public class StringCopyExample {
    public static void main(String[] args) {
        String original = "Hello, world!";
        String copy = new String(original);  // 通过构造函数拷贝,通过 String 的构造函数来创建一个新的字符串对象,该对象内容与原字符串相同。
        System.out.println(copy);  // 输出:Hello, world!
    }
}
public class StringArrayCopyExample {
    public static void main(String[] args) {
        char[] original = {'H', 'e', 'l', 'l', 'o'};
        char[] copy = new char[original.length];
        
        System.arraycopy(original, 0, copy, 0, original.length);
        //System.arraycopy(src, srcPos, dest, destPos, length):拷贝函数,从源数组 src 的 srcPos 索引开始,拷贝 length 个元素到目标数组 dest 的 `destPos` 索引开始的位置。
        System.out.println(new String(copy));  // 输出:Hello
    }
}
4.2 插入操作

insert(offset, str):这个方法将字符串 str 插入到 StringBuilder 中指定的 offset 位置,其他字符自动后移。

public class StringInsertExample {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("Hello world!");
        sb.insert(5, ", Java");  // 在索引 5 位置插入 ", Java"
        System.out.println(sb.toString());  // 输出:Hello, Java world!
    }
}
4.3 删除子字符串

delete(int start, int end):这个方法删除从索引 startend(不包括 end 索引)之间的字符。

public class StringDeleteExample {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("Hello, world!");
        sb.delete(5, 7);  // 删除从索引 5 到 7 的子串(不包含 7)
        System.out.println(sb.toString());  // 输出:Hello world!
    }
}
4.4 删除单个字符

deleteCharAt(int index):这个方法删除指定索引位置的单个字符。

public class StringDeleteCharExample {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("Hello, world!");
        sb.deleteCharAt(5);  // 删除索引位置 5 的字符
        System.out.println(sb.toString());  // 输出:Hello world!
    }
}
4.5 使用 String.replace() 替换子串

replace(CharSequence target, CharSequence replacement):这个方法将字符串中所有与 target 匹配的部分替换为 replacement

public class StringReplaceExample {
    public static void main(String[] args) {
        String original = "Hello, world!";
        String replaced = original.replace("world", "Java");
        System.out.println(replaced);  // 输出:Hello, Java!
    }
}
4.6 使用 StringBuilder.replace() 替换子串

replace(int start, int end, String str):这个方法将 StringBuilder 中从 startend 索引之间的字符替换为给定的 str

public class StringBuilderReplaceExample {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("Hello, world!");
        sb.replace(7, 12, "Java");  // 替换从索引 7 到 12 之间的子串为 "Java"
        System.out.println(sb.toString());  // 输出:Hello, Java!
    }
}

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;