【Java高级语法】(五)字符串操作类String:几乎每天都会用到的String类,你还在踩坑吗?~

news2024/11/18 3:28:16

Java高级语法详解之字符串操作类String

  • :one: 概念
  • :two: 使用
    • 2.1 创建字符串对象
    • 2.2 字符串的比较
    • 2.3 字符串长度
    • 2.4 字符串连接
    • 2.5 字符串截取
    • 2.6 字符串的查找和替换
    • 2.7 字符串的切割和拆分
    • 2.8 字符串和其他类型的转换
    • 2.9 字符串的格式化
    • 2.10 字符串的判断
    • 2.11 手动入池
    • 2.12 其他操作
    • 2.13 小结
  • :three: 字符串常量池
  • :four: StringBuffer类
  • :five: StringBuilder类
  • :six: String、StringBuffer和StringBuilder的对比
  • :bookmark_tabs: 本文源码下载地址

1️⃣ 概念

Java的String类是Java标准库中最常用的类之一。它用于表示字符串,并提供了许多用于操作和处理字符串的方法。

Java的String类的概念源自于C语言中的字符数组。然而,为了方便使用和提供更多功能,Java设计者将String类定义为一个引用类型,而不是像C语言中的字符数组那样是一个基本数据类型。

Java的String类提供了丰富的方法来处理字符串,包括字符串连接、查找子字符串、比较字符串、提取字符、替换字符、大小写转换等等。这些方法使得在Java中处理字符串变得非常方便和灵活。

与其他编程语言相比,Java的String类的优势在于字符串是不可变的(immutable),也就是说一旦创建,字符串的内容就不可修改。这种不可变性使得字符串具有更好的线程安全性。

2️⃣ 使用

2.1 创建字符串对象

在Java中,我们可以使用以下两种方式创建一个String类型的对象:

public void createString(){
        //1、直接赋值
        String str1 = "Hello";
        //2、构造方法
        String str2 = new String("World");
    }

上述代码中,第一种方式使用字符串字面量直接创建一个字符串对象,而第二种方式通过关键字new创建一个新的字符串对象。

需要注意的是,String类是不可变的,意味着一旦创建了一个字符串对象,就不允许对其进行修改。每次修改字符串时,实际上是创建了一个全新的字符串对象,因此在频繁修改字符串时需要特别注意性能问题。

🔍 String类的两种实例化方式之间有什么区别?

1、直接赋值
String类的设计使⽤了共享设计模式,JVM底层会自动维护一个字符串的对象池(对象数组)。
采用直接赋值 的方式进行对象实例化操作,那么该实例化对象(字符串内容)将自动保存到对象池 之中。
如果下次继续使用直接赋值的方式声明String类对象,此时对象池之中若已有相同内容,则直接进行引用;若没有,则创建新的字符串对象而后将其保存在对象池之中。

2、构造方法
构造方法方式的实例化,JVM会先在堆上创建一个匿名字符串,再将这个字符串复制一份并由变量指向,导致出现垃圾空间(匿名String对象),且此方式不会将该字符串对象加入到JVM的 “字符串常量池” 中,导致字符串共享问题。
解决办法是使用String类的intern()方法将以构造方法方式创建的对象手动加入到"字符串常量池"中。

2.2 字符串的比较

在Java中,用于比较字符串的内容是否相同有两种方法:equals()equalsIgnoreCase()

  • boolean equals(Object anObject):比较两个字符串的内容是否相同;
  • boolean equalsIgnoreCase(String anotherString):忽略字符串的大小写,比较两个字符串的内容;
  • int compareTo(String anotherString):按照字符编码比较字符串大小,结果=0表示相等、>0表示大于、<0表示小于。

例如:

public static void equalsMethod(){
        String str1 = "hello";
        String str2 = "Hello";

        System.out.println(str1.equals(str2));  
        System.out.println(str1.equalsIgnoreCase(str2));  
        System.out.println(str1.compareTo(str2));
    }

运行结果:

false
true
32

2.3 字符串长度

要获取字符串的长度,可以使用int length()方法,如下所示:

public static void lengthMethod(){
	String str = "Hello World";
    int length = str.length();
    System.out.println(length);
}

运行结果:

11

2.4 字符串连接

在Java中,可以使用+运算符或String concat(String str)方法来拼接字符串。如下:

public static void concatMethod(){
        String str1 = "Hello";
        String str2 = "World";
        String result1 = str1 + ", " + str2;
        String result2 = str1.concat(", ").concat(str2);
        System.out.println(result1); 
        System.out.println(result2);
    }

需要注意的是,频繁拼接字符串时,使用StringBuilderStringBuffer类会更高效。下文会详细介绍关于这这两个类的更多情况。

运行结果:

Hello, World
Hello, World

2.5 字符串截取

要从一个字符串中截取子串,可以使用substring(int beginIndex, int endIndex)方法和substring(int beginIndex)方法。

  • substring(int beginIndex, int endIndex)方法用来截取从第一个参数表示的起始位置(包括)到第二个参数表示结束位置(不包括)的子字符串;
  • substring(int beginIndex)方法用于从从第一个参数表示的指定位置截取到字符串末尾。

如下:

public static void substringMethod(){
        String str = "Hello World!";
        String substr = str.substring(6, 11);
        String substr2 = str.substring(6);
        System.out.println(substr);
        System.out.println(substr2);
    }

运行结果:

World
World!

2.6 字符串的查找和替换

🍎 查找
对于字符串的查找操作,常用的方法有indexOf(int ch)lastIndexOf(int ch)。它们用于返回指定字符或子串在字符串中的位置。

  • indexOf(int ch)indexOf(String str):从前往后的正向查找指定字符或子串在字符串中的位置。若找不到,则返回-1;
  • lastIndexOf(int ch)lastIndexOf(String str):从后往前的反向查找指定字符或子串在字符串中的位置。若找不到,则返回-1;
  • charAt(int index):获取指定位置的字符。

如下:

public static void findIndexMethod(){
        String str = "Hello World";
        int index1 = str.indexOf('o');
        int index2 = str.indexOf("World");
        int lastIndex1 = str.lastIndexOf('o');
        int lastIndex2 = str.lastIndexOf("World");
        System.out.println(index1);
        System.out.println(index2);
        System.out.println(lastIndex1);
        System.out.println(lastIndex2);

        char c = str.charAt(0);
        System.out.println(c);
    }

运行结果:

4
6
7
6
H

🍊 替换
Java中提供了多个方法用于替换字符串中的字符或子串,分别是:

  • replace(char oldChar, char newChar) 方法用于将字符串中的指定字符 替换为新字符。该方法会返回一个新字符串,原始字符串不会改变。若原始字符串中有多个匹配的字符,所有匹配的字符都会被替换;

  • replace(CharSequence target, CharSequence replacement) 方法用于将字符串中与目标字符序列 匹配的部分替换为指定字符序列。该方法同样会返回一个新字符串,而不改变原始字符串;
    注意这个方法的参数是 CharSequence 类型,这意味着可以传递任何实现了 CharSequence 接口的对象,包括 StringStringBuilder 等。这使得它更具灵活性,可以进行更复杂的字符串替换操作;

  • replaceFirst(String regex, String replacement)方法将字符串中首次出现的与正则表达式regex匹配的部分替换;

  • replaceAll(String regex, String replacement) 方法会将字符串中所有与正则表达式regex匹配的部分全部替换。

如下:

public static void replaceMethod(){
        String str = "Hello World";
        String newStr1 = str.replace('l', 'L');
        String newStr2 = str.replace("World", "Java");
        System.out.println(newStr1);
        System.out.println(newStr2);

        String newStr3 = str.replaceFirst("l", "L");
        String newStr4 = str.replaceAll("l", "L");
        System.out.println(newStr3);
        System.out.println(newStr4);
    }

运行结果:

HeLLo WorLd
Hello Java
HeLlo World
HeLLo WorLd

2.7 字符串的切割和拆分

🍒 切割
字符串的切割操作主要通过split(String regex)方法来实现,其中参数regex是一个正则表达式,用于指定分隔符。

如下:

public static void splitMethod(){
        String str = "Java is a programming language";
        String[] splitStr = str.split(" ");
        for (String s : splitStr) {
            System.out.println(s);
        }
    }

输出结果:

Java
is
a
programming
language

🍉 拆分
拆分字符串与切割类似,使用的方法是split(String regex, int limit)limit参数指定返回的数组长度限制。

如下:

public static void splitLimitMethod(){
        String str = "Java,is,a,programming,language";
        String[] splitStr = str.split(",", 3);
        for (String s : splitStr) {
            System.out.println(s);
        }
    }

输出结果:

Java
is
a,programming,language

2.8 字符串和其他类型的转换

Java中提供了大量用于字符串和其他数据类型转换的方法:

  • toCharArray():将字符串转换为字符数组;
  • String.valueOf(Object obj):将其他类型转换为字符串;
  • getBytes():使用平台的默认字符集将此 字符串编码为字节数组;
  • getBytes(String charsetName):使用指定字符集将 字符串编码为字节数组。

同时,各个包装类也有对字符串转换的支持:

  • int intValue = Integer.parseInt(stringValue); 将字符串转换为整数;
  • double doubleValue = Double.parseDouble(stringValue); 将字符串转换为双精度浮点数;
  • float floatValue = Float.parseFloat(stringValue); 将字符串转换为单精度浮点数;
  • boolean booleanValue = Boolean.parseBoolean(stringValue); 将字符串转换为布尔值。

关于包装类对字符串转换的操作支持更多情况,请参考我的另一篇文章:
【Java高级语法】(四)包装类:关于包装类的那些细节你都清楚吗?~

如下:

public static void changeTypeMethod(){
        String str = "Hello, world!";

        // 将字符串转换为字符数组
        char[] charArray = str.toCharArray();
        System.out.println("字符串转换为字符数组:");
        for (char c : charArray) {
            System.out.print(c + "、");
        }
        System.out.println();

        // 将其他类型转换为字符串
        int number = 123;
        String numberStr = String.valueOf(number);
        System.out.println("将整数转换为字符串:" + numberStr);

        double decimal = 3.14;
        String decimalStr = String.valueOf(decimal);
        System.out.println("将浮点数转换为字符串:" + decimalStr);

        boolean bool = true;
        String boolStr = String.valueOf(bool);
        System.out.println("将布尔值转换为字符串:" + boolStr);

        // 使用平台的默认字符集将字符串编码为字节数组
        byte[] bytes1 = str.getBytes();
        System.out.println("默认字符集下的字节数组:");
        for (byte b : bytes1) {
            System.out.print(b + " ");
        }
        System.out.println();

        // 使用指定字符集将字符串编码为字节数组(UTF-8)
        byte[] bytes2 = str.getBytes(Charset.forName("UTF-8"));
        System.out.println("UTF-8字符集下的字节数组:");
        for (byte b : bytes2) {
            System.out.print(b + " ");
        }
        System.out.println();

        // 使用指定字符集将字符串编码为字节数组(GBK)
        byte[] bytes3 = str.getBytes(Charset.forName("GBK"));
        System.out.println("GBK字符集下的字节数组:");
        for (byte b : bytes3) {
            System.out.print(b + " ");
        }
        System.out.println();
    }

输出结果:

字符串转换为字符数组:
H、e、l、l、o、,、 、w、o、r、l、d、!、
将整数转换为字符串:123
将浮点数转换为字符串:3.14
将布尔值转换为字符串:true
默认字符集下的字节数组:
72 101 108 108 111 44 32 119 111 114 108 100 33 
UTF-8字符集下的字节数组:
72 101 108 108 111 44 32 119 111 114 108 100 33 
GBK字符集下的字节数组:
72 101 108 108 111 44 32 119 111 114 108 100 33 

2.9 字符串的格式化

Java中使用String.format()方法可以对字符串进行格式化操作。

  • String.format(String format, Object... args):使用格式规范化字符串。第一个参数是格式字符串,后续参数是需要插入到格式字符串中的变量。

如下:

public static void formatMethod(){
        int number = 123;
        double decimal = 3.14;

        // 使用格式化字符串
        String formattedString = String.format("The number is %d and the decimal is %.2f", number, decimal);
        System.out.println("格式化字符串:" + formattedString);
    }

输出结果:

格式化字符串:The number is 123 and the decimal is 3.14

2.10 字符串的判断

Java中使用String.format()方法可以对字符串进行格式化操作。

  • boolean contains(String s):判断该字符串是否包含传进来的字符串;
  • boolean startsWith(String prefix):判断字符串是否以传进来的字符串开头;
  • boolean endsWith(String suffix):判断字符串是否以传进来的字符串结尾;
  • boolean isEmpty():判断字符串是否为空。

如下:

public static void judgmentMethod(){
        String str = "Hello, World!";

        // 判断字符串是否包含传进来的字符串
        String searchStr1 = "Hello";
        boolean containsStr1 = str.contains(searchStr1);
        System.out.println("字符串 \"" + str + "\" 是否包含 \"" + searchStr1 + "\": " + containsStr1);

        String searchStr2 = "ChinaAi";
        boolean containsStr2 = str.contains(searchStr2);
        System.out.println("字符串 \"" + str + "\" 是否包含 \"" + searchStr2 + "\": " + containsStr2);

        // 判断字符串是否以传进来的字符串开头
        String prefix1 = "Hello";
        boolean startsWithPrefix1 = str.startsWith(prefix1);
        System.out.println("字符串 \"" + str + "\" 是否以 \"" + prefix1 + "\" 开头: " + startsWithPrefix1);

        String prefix2 = "Hi";
        boolean startsWithPrefix2 = str.startsWith(prefix2);
        System.out.println("字符串 \"" + str + "\" 是否以 \"" + prefix2 + "\" 开头: " + startsWithPrefix2);

        // 判断字符串是否以传进来的字符串结尾
        String suffix1 = "World!";
        boolean endsWithSuffix1 = str.endsWith(suffix1);
        System.out.println("字符串 \"" + str + "\" 是否以 \"" + suffix1 + "\" 结尾: " + endsWithSuffix1);

        String suffix2 = "Java";
        boolean endsWithSuffix2 = str.endsWith(suffix2);
        System.out.println("字符串 \"" + str + "\" 是否以 \"" + suffix2 + "\" 结尾: " + endsWithSuffix2);

        // 判断字符串是否为空
        boolean isEmpty = str.isEmpty();
        System.out.println("字符串 \"" + str + "\" 是否为空: " + isEmpty);
    }

输出结果:

字符串 "Hello, World!" 是否包含 "Hello": true
字符串 "Hello, World!" 是否包含 "ChinaAi": false
字符串 "Hello, World!" 是否以 "Hello" 开头: true
字符串 "Hello, World!" 是否以 "Hi" 开头: false
字符串 "Hello, World!" 是否以 "World!" 结尾: true
字符串 "Hello, World!" 是否以 "Java" 结尾: false
字符串 "Hello, World!" 是否为空: false

2.11 手动入池

在Java中,通过手动将字符串加入字符串池,可以实现字符串的共享,从而优化内存使用。可以使用以下方式将字符串手动添加到字符串池中:

  • intern():这个方法会返回字符串池中对应的字符串,如果池中没有该字符串,则将它添加到池中并返回。

如下:

public static void internMethod(){
        // 创建两个不同的字符串对象
        String str1 = new String("Hello");
        String str2 = new String("Hello");

        // 执行intern()方法后,将字符串加入字符串常量池
        String internStr1 = str1.intern();
        String internStr2 = str2.intern();

        // 检查两个字符串是否引用同一个字符串对象
        boolean isSameObject = (internStr1 == internStr2);
        System.out.println("是否引用同一个字符串对象: " + isSameObject);

        // 使用equals()方法检查字符串内容是否相同
        boolean isEqual = internStr1.equals(internStr2);
        System.out.println("字符串内容是否相同: " + isEqual);
    }

输出结果:

是否引用同一个字符串对象: true
字符串内容是否相同: true

2.12 其他操作

Java中String 类还包括以下一些操作方法:

  • toLowerCase():将字符串中的英文字母转小写;
  • toUpperCase():将字符串中的英文字母转大写;
  • trim():去掉字符串左右两边的空格。

如下:

public static void otherMethod(){
        String input = "   Hello, World!   ";
        System.out.println("原始字符串: " + input);

        // 转小写
        String lowercase = input.toLowerCase();
        System.out.println("转小写后: " + lowercase);

        // 转大写
        String uppercase = input.toUpperCase();
        System.out.println("转大写后: " + uppercase);

        // 去掉左右两边的空格
        String trimmed = input.trim();
        System.out.println("去掉空格后: " + trimmed);
    }

输出结果:

原始字符串:    Hello, World!   
转小写后:    hello, world!   
转大写后:    HELLO, WORLD!   
去掉空格后: Hello, World!

2.13 小结

本节介绍了Java中String类的各种操作支持方法,包括创建字符对象、比较字符串内容、获取长度、连接、截取、查找、替换、切割、拆分、转换、格式化等常用操作。String类是Java编程中十分重要的一部分,熟练掌握这些操作有助于开发出高效的程序。

操作类别方法说明
获取length() 获取字符串长度
charAt(int index) 获取指定位置的字符
indexOf(Char char)获取指定字符在字符串中首次出现的位置
lastIndexOf(Char char)反向查找指定字符在字符串中首次出现的位置
subString(int start)字符串截取,从指定位置到字符串末尾
subString(int start,int end)字符串截取,从指定位置到指定位置,范围左闭右开
比较equals(String s)比较字符串内容是否相同,区分大小写
equalsIgnoreCase(String s)比较字符串内容是否相同,不区分大小写
compareTo(String s)比较字符串大小(按照字符编码),结果=0表示相等、>0表示大于、<0表示小于
判断contains(String s)判断该字符串是否包含传进来的字符串
startsWith(String prefix)判断字符串是否以传进来的字符串开头
endsWith(String suffix)判断字符串是否以传进来的字符串结尾
isEmpty()判断字符串是否为空
拆分split(String regex)通过指定正则表达式分隔符来拆分字符串
split(String regex, int limit)通过指定正则表达式分隔符来拆分字符串,limit参数指定返回的数组长度限制
替换replaceFirst(String regex, String replacement)用新内容替换首个旧内容
replaceAll(String regex, String replacement)用新内容替换全部的旧内容
replace(char oldChar, char newChar)将字符串中的指定字符 替换为新字符
replace(CharSequence target, CharSequence replacement)将字符串中与目标字符序列 匹配的部分替换为指定字符序列
数据类型转换getBytes()使用平台的默认字符集将此 String 编码为byte 数组
getBytes(String charsetName)使用指定字符集将 String 编码为byte 数组
toCharArray()将字符串转化为char字符数组
valueOf(char[] data) 将传递的字符数组,组合成字符串
格式化String.format(String format, Object... args)使用格式规范化字符串。第一个参数是格式字符串,后续参数是需要插入到格式字符串中的变量
连接concat(String s)字符串连接
其他toLowerCase()转小写
toUpperCase()转大写
trim()去掉字符串左右两边的空格
手动入池intern()手动将字符串加入字符串常量池

3️⃣ 字符串常量池

前面我们介绍了String类的两种实例化方式,分别是将字符串存储在不同的内存位置。

第一种通过String类构造方法创建的对象,会存储在JVM内存结构的堆中。这些字符串对象在堆上分配空间,并包含有关字符串长度、字符内容等信息。使用方法和属性来操作和访问字符串对象。在实际使用时,使用这种方式是很少的。

而不同于第一种字符串存储方式,通过直接赋值的字符串是存储在方法区(也即元空间metaspace)的字符串常量池里的。字符串常量池是一个特殊的字符串存储区域,用于存储程序中的字符串常量。

字符串常量池主要有以下特点:

  • 字面量优化:编译器会对代码中的字符串常量进行优化,将其放入字符串常量池中。如果同一个字面量字符串在源代码中多次出现,只会保留其一个副本,以节省内存空间;

  • 共享和复用:字符串常量池中的字符串是共享的,意味着如果代码中使用了相同内容的字符串常量,它们将被存储为同一个对象。这种共享和复用能够提高性能并减少内存占用;

  • 运行时常量池:在Java中,字符串常量池是java.lang.String类的一个属性,属于其运行时常量池。除了存储字面量字符串,它还可以包含通过调用String类的intern()方法手动添加的字符串;

  • 不可变性:字符串常量池中的字符串是不可变的,即不允许修改操作。当对字符串进行拼接、截取等操作时,会生成新的字符串对象,而不影响原始的字符串对象。这种不可变性提供了字符串的线程安全性和缓存机制。

总结来说,字符串常量池是为了优化字符串的存储和提高性能而设计的特殊存储区域,其中存放着程序中使用的字符串常量,并且这些字符串是共享和不可变的。

4️⃣ StringBuffer类

StringBuffer类是Java中一个被广泛使用的可变字符串类。它提供了许多方法来操作和修改字符串内容,而不会创建新的对象实例。

以下是StringBuffer类的一些重要特点:

  • 可变性:StringBuffer对象是可变的,意味着可以通过调用相应的方法对其内容进行修改,而不会创建新的对象。相比之下,String对象是不可变的,一旦创建后就无法更改;
  • 线程安全:StringBuffer类是线程安全的,这意味着它的方法在多线程环境中可以安全地使用,不会导致竞态条件或数据不一致的问题。然而,由于其需要额外的同步开销,这可能会影响性能。如果不需要线程安全的操作,可以使用非线程安全的兄弟类StringBuilder,它具有相似的功能但性能更高;
  • 性能考虑:由于字符串是可变的,可以在执行一系列操作后一次性获取最终结果,避免了频繁的字符串拷贝和内存分配,因此在某些情况下,StringBuffer比使用+concat()操作符连接字符串更高效。

以下是StringBuffer类的一些用法:

  • 字符串操作StringBuffer类提供了一系列方法来操作字符串,如添加字符、插入字符、替换字符、删除字符等。这些方法可以根据需要灵活地修改字符串内容;

  • 连接字符串StringBuffer类也可以用于高效地连接字符串,而不像String那样每次连接都创建一个新的字符串对象。append()方法用于在当前字符串末尾添加字符、字符串和其他数据类型的值;

  • 反转字符串StringBuffer类提供了reverse()方法,用于反转当前字符串的顺序。这对于需要逆序处理字符串的场景很有用。

下面是一个使用StringBuffer类的示例:

public static void main(String[] args) {
        // 创建一个空的StringBuffer对象
        StringBuffer sb = new StringBuffer();

        // 在末尾添加字符串
        sb.append("Hello");
        sb.append(" World!");

        // 输出:Hello World!
        System.out.println(sb.toString());

        // 在指定位置插入字符串
        sb.insert(5, "Java ");
        System.out.println(sb.toString());

        // 反转字符串
        sb.reverse();
        System.out.println(sb.toString());
    }

输出结果:

Hello World!
HelloJava  World!
!dlroW  avaJolleH

总之,StringBuffer类是处理可变字符串的强大工具,特别适用于需要经常修改字符串内容的场景。并且它的方法是线程安全的,可以在多线程环境中安全地使用,不会导致竞态条件或数据不一致的问题。但由于其需要额外的同步开销,也同时会影响一些性能。

5️⃣ StringBuilder类

StringBuilder 是 Java 中的一个类,它允许可变长度的字符串操作。与 String 类不同,StringBuilder 对象的长度和内容都可以修改。这意味着可以在已存在的字符串上进行添加、删除和修改操作,而无需创建新的对象。

以下是该类的一些重要特性:

  • 可变性StringBuilder 具有可变性,这意味着可以动态地更改字符串内容和长度;
  • 高效性:相对于直接使用 + 运算符连接字符串的方式,使用 StringBuilder 在性能上更高效。当需要频繁进行字符串操作时,使用 StringBuilder 可以减少系统开销。

以下是该类的一些使用方法:

  • 初始化:可以通过无参构造函数创建一个空的 StringBuilder 对象,或者可以根据已存在的字符串创建对象;还可以指定初始容量创建对象。
  • append()方法:用于在当前字符串末尾附加给定的数据;
  • delete()方法:用于删除当前字符串中指定范围内的字符;
  • insert()方法:用于将给定的数据插入到当前字符串的指定位置;
  • replace():该方法用于替换当前字符串指定范围内的字符;
  • reverse():该方法用于逆转当前字符串的字符顺序;
  • toString():该方法用于将 StringBuilder 对象转换为一个普通的字符串。

下面是一个使用StringBuilder类的示例:

public static void main(String[] args) {
        // 创建一个空的 StringBuilder 对象
        StringBuilder sb1 = new StringBuilder();
        // 根据已存在的字符串创建 StringBuilder 对象
        StringBuilder sb2 = new StringBuilder("Hello");
        // 指定初始容量创建 StringBuilder 对象
        StringBuilder sb3 = new StringBuilder(10);

        StringBuilder sb = new StringBuilder();
        sb.append("Hello");
        sb.append("World");
        System.out.println(sb.toString());

        sb.delete(5, 10);
        System.out.println(sb.toString());

        sb.insert(5, " World");
        System.out.println(sb.toString());

        sb.replace(5, 11, " Everybody");
        System.out.println(sb.toString());

        sb.reverse();
        System.out.println(sb.toString());

        String str = sb.toString();
        System.out.println(str);
    }

输出结果:

HelloWorld
Hello
Hello World
Hello Everybody
ydobyrevE olleH
ydobyrevE olleH

除了上面提到的常用方法之外,StringBuilder 还有其他一些方法可以查询和修改字符串。请参考 Java 官方文档 以获取更详尽的信息。

6️⃣ String、StringBuffer和StringBuilder的对比

String类:适用于少量的字符串不变的操作;
StringBuilder类:适用于单线程下在字符串缓冲区进行大量操作;
StringBuffer类:适用于多线程下在字符串缓冲区进行大量操作。

  • String类表示不可变的(immutable)字符串,该类是 final修饰的类,不能被继承且表示字符串常量(字符串常量一旦声明则不可改变,而字符串对象可以改变,改变的是其内存地址的指向),对String修改会产生新的对象,效率低。而StringBuilderStringBuffer均为可变字符串;
  • String类使用 +concat() 方法做数据的连接操作,而在StringBuffer类和StringBuilder类中使用 append()方法进行数据连接;
  • StringBuilder是非线程安全的,不保证同步所以在性能上较高;StringBuffer是线程安全的,该类方法都使用了 synchronized 修饰,所以符合多线程操作中的安全要求。

📑 本文源码下载地址

Java的String类讲解案例代码(String类使用:创建对象、比较、连接、截取、查找和替换、拆分…)
在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/654678.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

202319读书笔记|《春之海终日优哉游哉:谢芜村俳句300》——远山峡谷间樱花绽放,宇宙在其中

202319读书笔记&#xff5c;《春之海终日优哉游哉&#xff1a;谢芜村俳句300》——远山峡谷间樱花绽放&#xff0c;宇宙在其中 与谢芜村&#xff0c;小林一茶&#xff0c;芭蕉&#xff0c;与谢野晶子&#xff0c;俳句都很赞&#xff0c;虽多本书中略有重复&#xff0c;但多多观…

【备战秋招】每日一题:4月15日美团春招第一题:题面+题目思路 + C++/python/js/Go/java带注释

为了更好的阅读体检&#xff0c;为了更好的阅读体检&#xff0c;&#xff0c;可以查看我的算法学习博客第一题-字符串前缀 在线评测链接:P1235 题目内容 塔子哥是一名优秀的软件工程师&#xff0c;他的公司最近接到了一个新项目&#xff0c;需要在短时间内实现一个新的字符串…

微服务 springcloud 09.整合feign到项目一个子服务中

01.项目结构如下&#xff1a; 02.修改sp04-orderservice项目&#xff0c;添加feign&#xff0c;调用item service和user service 1.sp04-orderservice项目的pom.xml 添加以下依赖: actuator feign hystrix <?xml version"1.0" encoding"UTF-8"?>…

全链路压测演进之迭代式压测

目录 1.背景原因 2.压测流程改进分析 3.迭代式压测流程 4.全流程压测模式演进 5.压测模式对比 6.迭代式压测反馈效果 7.总结 1.背景原因 !! 做系统服务压测都是比较耗时耗人力的&#xff0c;特别是在生产环境上做压测&#xff0c;压测的时间都是在晚上23点后&#xff0c…

Linux之线程安全(上)

文章目录 前言一、预备知识1.线程的ID2.局部存储的验证3.线程的封装 二、线程安全问题1.抢票程序2.问题分析 三、Linux线程互斥1.概念临界资源临界区互斥原子性 2.互斥量概念接口 3.mutex的使用全局锁的使用局部锁的使用 总结 前言 本文从一个模拟生活中的抢票程序的例子引入线…

经典的设计模式22——职责链模式

文章目录 职责链模式 老感觉职责链模式和状态模式有点像&#xff0c;好像都能实现请假流程。百度来一波。 真是巧了&#xff0c;职责链&#xff0c;状态&#xff0c;策略&#xff0c;则三个长得好像。 职责链模式 定义&#xff1a; 使多个对象都有机会处理请求&#xff0c;从…

循环神经网络RNN用于分类任务

RNN是一类拥有隐藏状态&#xff0c;允许以前的输出可用于当前输入的神经网络&#xff0c; 输入一个序列&#xff0c;对于序列中的每个元素与前一个元素的隐藏状态一起作为RNN的输入&#xff0c;通过计算当前的输出和隐藏状态。当前的影藏状态作为下一个单元的输入... RNN的种类…

AMEYA:如何设计好DC-DC电源,注意事项有哪些

DC-DC变换器&#xff08;DC-DC converter&#xff09;是指在直流电路中将一个电压值的电能变为另一个电压值的电能的装置。DC-DC的layout非常重要&#xff0c;会直接影响到产品的稳定性与EMI效果。 DC-DC电源几点经验以及规则 1、处理好反馈环&#xff0c;反馈线不要走肖特基下…

基于JavaWeb的体育赛事平台的设计与实现

摘要 体育是随着社会生产力的发展而产生和发展的&#xff0c;在其漫长的历史中&#xff0c;由于社会、政治和经济发展的影响&#xff0c;其内容、形式、功能和操作方法不断变化。奥运会和世界杯等大型体育赛事代表着体育发展的顶峰&#xff0c;因为它们不仅给组织者带来了巨大…

【考研复习】李春葆新编C语言习题与解析(错误答案订正)持续更新

新编C语言习题与解析 做习题时发现有些错误答案&#xff0c;写篇博客进行改正记录。不对地方欢迎指正&#xff5e; 第二章 C. 其中b的表达形式错误&#xff0c;若加上0x1e2b则正确。所以C错误。 D. e后为整数。指数命名规则&#xff1a;e前有数&#xff0c;后有整数。所以D错…

实验篇(7.2) 15. 站对站安全隧道 - 多条隧道聚合(FortiGate-IPsec) ❀ 远程访问

【简介】虽然隧道冗余可以解决连接问题&#xff0c;但是当大量数据访问或要求访问不能中断时&#xff0c;隧道冗余就力不从心了。这种情况就要用到隧道聚合。但是对宽带的要求也高了&#xff0c;双端都至少需要二条宽带。 实验要求与环境 OldMei集团深圳总部部署了域服务器和ER…

C语言复合类型之结构(struct)篇(结构指针)

结构相关知识总结 什么是结构&#xff1f;结构的声明与简单使用结构的初始化结构中成员变量的访问结构的初始化器结构数组结构数组的声明结构数组的成员标识 结构的嵌套结构指针结构作为参数在函数中传递将结构成员作为参数进行传递将结构地址(指向结构的指针)作为参数进行传递…

AI数字人之语音驱动人脸模型Wav2Lip

1 Wav2Lip模型介绍 2020年&#xff0c;来自印度海德拉巴大学和英国巴斯大学的团队&#xff0c;在ACM MM2020发表了的一篇论文《A Lip Sync Expert Is All You Need for Speech to Lip Generation In The Wild 》&#xff0c;在文章中&#xff0c;他们提出一个叫做Wav2Lip的AI模…

面试题:完败的面试,被虐得体无完肤

经过上一轮的面试&#xff0c;我信心一下子就建立起来了&#xff0c;说巧不巧&#xff0c;前几周正好看到美团校招&#xff0c;想着试一下也不会怎样&#xff0c;就找了学长要了内推码&#xff0c;试着投递了一下&#xff0c;然后就通知周六参加笔试&#xff0c;结果惨不忍睹。…

flv 报错 Unsupported codec in video frame: 12

视频播放器播放 flv 报错 [TransmuxingController] > DemuxException: type CodecUnsupported, info Flv: Unsupported codec in video frame: 12 原因 主要是因为我们的播放器不支持 H.265 视频编码&#xff1b; 解决办法 方法一&#xff1a;将设备端的视频编码改为 …

FPGA实现USB3.0 UVC 相机HDMI视频输出 基于FT602驱动 提供工程源码和QT上位机源码

目录 1、前言2、UVC简介3、FT602芯片解读4、我这儿的 FT601 USB3.0通信方案5、详细设计方案基于FT602的UVC模块详解 6、vivado工程详解7、上板调试验证8、福利&#xff1a;工程代码的获取 1、前言 目前USB3.0的实现方案很多&#xff0c;但就简单好用的角度而言&#xff0c;FT6…

基于多层感知机MLP的数据预测与误差分析的完整matlab代码分享

多层感知机(MLP,Multilayer Perceptron)也叫人工神经网络(ANN,Artificial Neural Network),除了输入输出层,它中间可以有多个隐层,最简单的MLP只含一个隐层,即三层的结构。多层感知器(multilayer Perceptron,MLP)是指可以是感知器的人工神经元组成的多个层次。MPL的…

在Windows和Linux系统上,用C语言实现命令行下输入密码回显星号和完全隐藏密码

本篇目录 引子在Windows 上实现在Linux上实现回显星号代码解读运行 完全隐藏运行 引子 在Windows系统上&#xff0c;当我们使用命令行和MySQL进行交互时&#xff0c;第一步就是要输入密码&#xff1a; -p后面的参数紧跟着的就是相应用户的密码。然而这种方式并不安全&#xff…

【数学建模】2019 年全国大学生数学建模竞赛C题全国一等奖获奖论文

2021 年高教社杯全国大学生数学建模竞赛题目 机场的出粗车问题 大多数乘客下飞机后要去市区&#xff08;或周边&#xff09;的目的地&#xff0c;出租车是主要的交通工具之一。国内多数机场都是将送客&#xff08;出发&#xff09;与接客&#xff08;到达&#xff09;通道分开…

2. windows系统下在QT中配置OPenCV开发环境

1. 说明: 在Windows系统中配置相对简单,不需要对下载的源码进行编译,在官网上下载的OPenCV可以直接使用,本文系统版本为win10,opencv是最新版本4.7.0。 效果展示: 2. 配置步骤: 2.1 下载OPenCV压缩包 打开opencv的官网OPenCV下载地址,可以在其页面内下载到最新的压…