String和StringBuilder用法(附15道练习题)

目录

一、String

1. 字符串构造方法

2. 其它类型向字符串转换

3. 字符串向其它类型转换

4. 字符串长度

5. 字符串查找

6. 字符串截取

7. 字符串比较

8. 字符串分割

9. 字符串替换

10.字符串其他常用方法

11. 字符串与 Stream API

二、StringBuilder

1. 构造方法

2. 追加

3. 插入

4. 删除

5. 替换

6. 反转

7. 其他方法

8. StringBuilder和StringBuffer的区别

9. String, StringBuilder和StringBuffer的执行速度对比

三、练习

1. 将给定的字符串进行反转。

2. 将给定的字符串重复n次。

3. 删除给定字符串中的所有空格。

4. 查找字符串中指定子串出现的次数。

5. 使用StringBuilder截取字符串的前6个字符。

6. 使用StringBuilder反转字符串中的单词顺序,单词之间以单个空格分隔。如 "this is a test" 转换成 "test a is this"

7. 使用StringBuilder对字符串中的字符进行字典序排序。

8. 将字符串中的每个单词首字母转换为大写。

9. 将字符串中连续的空格替换为单个空格。

10. 删除字符串中所有的指定字符。

11. 去除字符串中所有重复的字符。

12. 判断一个字符串是否为回文。

13. 统计字符串中每个字母出现的次数。

14. 计算字符串中元音字母(a, e, i, o, u)的数量。

15. 使用StringBuilder将字符串中的每个单词长度缩短到k个字符(如果单词长度超过k),然后返回修改后的字符串。


一、String

1. 字符串构造方法

三种方法:

  • 常量串构造
  • new String对象构造
  • 字符数组构造
public class Main {
    public static void main(String[] args) {

        // 字符串常量构造
        String s1 = "hello string";
        System.out.println(s1); //hello string

        // new String 对象构造
        String s2 = new String("hello string");
        System.out.println(s2); //hello string

        // 使用字符数组进行构造
        char[] chars = {'h', 'e', 'l', 'l', 'o', ' ', 's', 't', 'r', 'i', 'n', 'g'};
        String s3 = new String(chars);
        System.out.println(s3); //hello string

    }
}

2. 其它类型向字符串转换

  • 基本类型向字符串的转换:valueOf
  • char[]向字符串的转换:构造方法或valueOf
  • StringBuilder向字符串的转换:toString
  • String[]数组和List<String>列表向字符串的转换:join
  • 将数组内容生成字符串:toString
  • LocalDateTime日期时间类向字符串的转换:format
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {

        // 基本类型转换成字符串
        char[] chars = {'h', 'e', 'l', 'l', 'o', ' ', 's', 't', 'r', 'i', 'n', 'g'};
        String s1 = String.valueOf(123);         //也可以""+123,但不推荐
        String s2 = String.valueOf(123.456);     //也可以""+123.456,但不推荐
        String s3 = String.valueOf('a');         //也可以""+'a',但不推荐
        String s4 = String.valueOf(true);        //也可以""+true,但不推荐
        String s5 = String.valueOf(chars);
        System.out.println(s1);    //123
        System.out.println(s2);    //123.456
        System.out.println(s3);    //a
        System.out.println(s4);    //true
        System.out.println(s5);    //hello string

        // StringBuilder转换成字符串
        StringBuilder sb = new StringBuilder("abc");
        String s6 = sb.toString();
        System.out.println(s6);

        // String数组转换成字符串
        String[] array = {"apple", "banana", "cherry"};
        String s7 = String.join(", ", array);
        System.out.println(s7); // 输出: apple, banana, cherry

        // String列表转换成字符串
        List<String> list = Arrays.asList("apple", "banana", "cherry");
        String s8 = String.join(", ", list);
        String s9 = list.stream().collect(Collectors.joining(", "));
        System.out.println(s8); // 输出: apple, banana, cherry
        System.out.println(s9); // 输出: apple, banana, cherry

        // toString将数组内容生成字符串
        String s10 = Arrays.toString(chars);
        String s11 = Arrays.toString(array);
        String s12 = list.toString();
        System.out.println(s10); // [h, e, l, l, o,  , s, t, r, i, n, g]
        System.out.println(s11); // [apple, banana, cherry]
        System.out.println(s12); // [apple, banana, cherry]

        // 日期时间类向字符串的转换
        LocalDateTime dateTime = LocalDateTime.now();   // 2024-07-15T17:31:49.451958800
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String s13 = dateTime.format(formatter);
        System.out.println(s13);                        // 2024-07-15 17:31:49
    }
}

3. 字符串向其它类型转换

  • 转换成基本类型:Integer,Double等
  • 转换成字符数组:char[]
  • 转换成字符缓冲:StringBuilder,StringBuffer
  • 转换成日期类型:LocalDate,LocalTime,LocalDateTime
  • 转换成大数类型:BigInteger,BigDecimal
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

public class Main {
    public static void main(String[] args) {
        
        // 转换成 Integer
        String integerStr = "123";
        int i = Integer.parseInt(integerStr);
        System.out.println(i); //123

        // 转换成 Double
        String doubleStr = "123.456";
        double v = Double.parseDouble(doubleStr);
        System.out.println(v); //123.456

        // 转换成 char[]
        String str = "hello world";
        char[] charArray = str.toCharArray();
        System.out.println(Arrays.toString(charArray)); //[h, e, l, l, o,  , w, o, r, l, d]

        // 转换成 StringBuilder
        StringBuilder stringBuilder = new StringBuilder(str);
        System.out.println(stringBuilder); //hello world

        // 转换成 StringBuffer
        StringBuffer stringBuffer = new StringBuffer(str);
        System.out.println(stringBuffer); //hello world

        // 转换成 LocalDate
        String dateStr = "2023-04-01";
        LocalDate date = LocalDate.parse(dateStr);
        System.out.println(date); //2023-04-01

        // 转换成 LocalTime
        String timeStr = "13:45:30";
        LocalTime time = LocalTime.parse(timeStr);
        System.out.println(time); //13:45:30

        // 转换成 LocalDateTime
        String dateTimeStr = "2023-04-01T13:45:30";
        LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr);
        System.out.println(dateTime); //2023-04-01T13:45:30

        // 转换成 BigInteger
        String bigIntStr = "12345678901234567890";
        BigInteger bigInt = new BigInteger(bigIntStr);
        System.out.println(bigInt); //12345678901234567890

        // 转换成 BigDecimal
        String bigDecStr = "12345.678901234567890";
        BigDecimal bigDec = new BigDecimal(bigDecStr);
        System.out.println(bigDec); //12345.678901234567890
        
    }
}

4. 字符串长度

import java.util.List;

public class Main {
    public static void main(String[] args) {

        String str1 = "hello";
        String str2 = "你好";
        String str3 = "";
        int[] intArr = {1, 2, 3, 4, 5};
        String[] strArr = {"1", "2", "3", "4"};
        List<String> strList = List.of("1", "2", "3", "4");

        System.out.println(str1.length());    //5
        System.out.println(str2.length());    //2
        System.out.println(str3.length());    //0
        System.out.println(str3.isEmpty());   //true
        System.out.println(intArr.length);    //5
        System.out.println(strArr.length);    //4
        System.out.println(strList.size());   //4

    }
}

5. 字符串查找

charAt方法:

  • char (int index):输入位置index,找单个字符。

indexOf 方法:

  • int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引。
  • int indexOf(String str, int fromIndex):从指定的索引处开始,返回第一次出现的指定子字符串在此字符串中的索引。

lastIndexOf 方法:

  • int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引。
  • int lastIndexOf(String str, int fromIndex):从指定的索引处开始向后搜索,返回第一次出现的指定子字符串在此字符串中的索引。

contains 方法:

  • boolean contains(CharSequence s):当且仅当此字符串包含指定的 char 值序列时,返回 true。

startsWith 方法:

  • boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始。
  • boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始。

endsWith 方法:

  • boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束。

matches 方法(正则表达式匹配):

  • boolean matches(String regex):告知此字符串是否匹配给定的正则表达式。
public class Main {
    public static void main(String[] args) {

        // 使用charAt查找第5个字符
        String str = "Hello, World! Hello, Java";
        char c = str.charAt(5);
        System.out.println(c); // 输出: ,

        // 使用indexOf查找子字符串"World"的索引位置
        int index1 = str.indexOf("World");
        System.out.println("indexOf('World')的结果是: " + index1); // 输出: 7
        int index2 = str.indexOf('e');
        System.out.println("indexOf('e')的结果是: " + index2); // 输出: 1

        // 使用lastIndexOf查找子字符串"Hello"的最后一个索引位置
        int lastIndex = str.lastIndexOf("Hello");
        System.out.println("lastIndexOf('Hello')的结果是: " + lastIndex); // 输出: 26

        // 使用contains检查字符串是否包含子字符串"Spring"
        boolean contains = str.contains("Spring");
        System.out.println("contains('Spring')的结果是: " + contains); // 输出: false

        // 使用startsWith检查字符串是否以"Hello"开头
        boolean startsWith = str.startsWith("Hello");
        System.out.println("startsWith('Hello')的结果是: " + startsWith); // 输出: true

        // 使用endsWith检查字符串是否以"Java"结尾
        boolean endsWith = str.endsWith("Java");
        System.out.println("endsWith('Java')的结果是: " + endsWith); // 输出: true

        // 使用matches检查字符串是否完全匹配正则表达式
        boolean matches = str.matches(".*Java.*");
        System.out.println("matches('.*Java.*')的结果是: " + matches); // 输出: true

        // 使用matches检查字符串是否匹配特定模式(例如,是否包含至少一个数字)
        boolean hasDigit = str.matches(".*\\d.*");
        System.out.println("matches('.*\\d.*')的结果是: " + hasDigit); // 输出: false(因为str中没有数字)

    }
}

6. 字符串截取

String 类提供了两种形式的 substring 方法,用于截取字符串的一部分。

  • String substring(int beginIndex) 从指定的索引位置开始截取字符串,直到字符串末尾。
  • String substring(int beginIndex, int endIndex) 从指定的 beginIndex 索引位置开始截取字符串,直到 endIndex 索引位置(但不包括 endIndex 位置的字符)。
public class Main {
    public static void main(String[] args) {
        String str = "Hello, World!";

        // 从索引7开始截取到字符串末尾
        String sub1 = str.substring(7);
        System.out.println(sub1); // 输出: World!

        // 从索引0开始截取到索引5(不包括索引5)
        String sub2 = str.substring(0, 5); //也可以理解成从0开始,截取5-0个字符
        System.out.println(sub2); // 输出: Hello
        
    }
}

7. 字符串比较

  • == 操作符用于比较两个对象的引用是否相同,即它们是否指向同一个内存地址。
  • equals 方法用于比较两个字符串是否具有相同的字符序列。
  • equalsIgnoreCase 方法用于比较两个字符串是否具有相同的字符序列,而不考虑它们的大小写。
  • compareTo 方法用于按照字典顺序比较两个字符串。它返回一个整数值,表示第一个字符串与第二个字符串的差值。
import java.util.Arrays;
import java.util.Collections;

public class Main {
    public static void main(String[] args) {

        String str1 = "Apple";
        String str2 = "Banana";
        String str3 = "apple";
        String str4 = new String("Apple");

        // 使用equals方法比较字符串
        boolean equalsResult = str1.equals(str2);
        System.out.println("使用equals比较str1和str2: " + equalsResult); // 输出: false

        // 使用==比较字符串
        System.out.println(str1 == str4); //输出: false

        // 使用equalsIgnoreCase方法比较字符串
        boolean equalsIgnoreCaseResult = str1.equalsIgnoreCase(str3);
        System.out.println("使用equalsIgnoreCase比较str1和str3: " + equalsIgnoreCaseResult); // 输出: true

        // 使用compareTo方法比较字符串
        int compareToResult = str1.compareTo(str2); // Apple比Banana小,所以是负数
        System.out.println("使用compareTo比较str1和str2: " + compareToResult); // 输出: -1

        // 使用compareToIgnoreCase方法比较字符串
        int compareToIgnoreCaseResult = str1.compareToIgnoreCase(str3);
        System.out.println("使用compareToIgnoreCase比较str1和str3: " + compareToIgnoreCaseResult); // 输出: 0

        // 字符串数组降序排序
        String[] fruits = {"Apple", "Orange", "Banana", "Grape", "Mango"};
        // 使用Arrays.sort()方法进行排序,然后使用Collections.reverseOrder()进行降序排列
        Arrays.sort(fruits, Collections.reverseOrder());
        System.out.println(Arrays.toString(fruits)); //[Orange, Mango, Grape, Banana, Apple]

    }
}

8. 字符串分割

  • public String[] split(String regex)
  • public String[] split(String regex, int limit)

regex:这是用于匹配分隔符的正则表达式。如果该正则表达式中包含特殊字符,则需要对其进行转义。

limit:这是结果数组的最大长度。如果非负,则最多有 limit 个结果,最后一个结果会包含所有超出分隔符的剩余输入。

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        // 示例字符串
        String text = "apple-banana-orange-grape";

        // 使用-分割字符串
        String[] fruits = text.split("-");
        System.out.println(Arrays.toString(fruits)); //[apple, banana, orange, grape]

        // 使用-分割字符串,限制结果数量
        String[] limitedFruits = text.split("-", 3);
        System.out.println(Arrays.toString(limitedFruits)); //[apple, banana, orange-grape]

        // 使用空格分割字符串
        String sentence = "This is a sample sentence.";
        String[] words = sentence.split(" ");
        System.out.println(Arrays.toString(words)); //[This, is, a, sample, sentence.]

        // 使用空串分割字符串
        String[] chars = sentence.split("");
        System.out.println(Arrays.toString(chars)); //[T, h, i, s,  , i, s,  , a,  , s, a, m, p, l, e,  , s, e, n, t, e, n, c, e, .]

        // 使用正则表达式分割字符串,匹配多个空格或制表符
        String spacedSentence = "This    is\t a\t sample\n sentence.";
        String[] spacedWords = spacedSentence.split("\\s+");
        System.out.println(Arrays.toString(spacedWords)); //[This, is, a, sample, sentence.]

    }
}

9. 字符串替换

  • replace(char oldChar, char newChar): 将当前字符串中的所有oldChar字符替换成newChar字符。
  • replace(CharSequence target, CharSequence replacement): 将当前字符串中的所有target字符串替换成replacement字符串。
  • replaceAll(String regex, String replacement):使用给定的replacement替换掉当前字符串中所有符合正则表达式regex的部分。
  • replaceFirst(String regex, String replacement):使用给定的replacement替换掉当前字符串中第一个符合正则表达式regex的部分。
public class Main {
    public static void main(String[] args) {
        String str = "Hello World!";

        // 替换字符'o'为'*'
        String str1 = str.replace('o', '*');
        System.out.println(str1); // 输出: Hell* W*rld!

        // 替换字符串"World"为"Universe"
        String str2 = str.replace("World", "Universe");
        System.out.println(str2); // 输出: Hello Universe!

        // 使用正则表达式替换所有字符'o'为'*'
        String str3 = str.replaceAll("o", "*");
        System.out.println(str3); // 输出: Hell* W*rld!

        // 使用正则表达式替换第一个字符'o'为'*'
        String str4 = str.replaceFirst("o", "*");
        System.out.println(str4); // 输出: Hell* World!

        // 使用正则表达式替换所有身份证号码的后六位为"******"
        String idNumbers = "My ID is 123456789012345678 and my friend's ID is 567890123456789012";
        String protectedIds = idNumbers.replaceAll("(\\d{12})\\d{6}", "$1******");
        System.out.println(protectedIds); // 输出: My ID is 123456789012****** and my friend's ID is 567890123456******

    }
}

10.字符串其他常用方法

  • isEmpty()方法判断字符串是不是空串
  • trim()方法去除字符串两端的空白字符
  • toUpperCase()方法将字符串转换为大写
  • toLowerCase()方法将字符串转换为小写
  • format()方法格式化字符串
public class Main {
    public static void main(String[] args) {
        // 使用isEmpty()方法字符串是否为空串
        String strEmpty = "";
        System.out.println(strEmpty.isEmpty()); // 输出: true

        // 使用trim()方法去除字符串两端的空白字符
        String strTrimmed = "   Hello World!   ".trim();
        System.out.println(strTrimmed); // 输出: Hello World!

        // 使用toUpperCase()方法将字符串转换为大写
        String strUpperCase = "Hello World!".toUpperCase();
        System.out.println(strUpperCase); // 输出: HELLO WORLD!

        // 使用toLowerCase()方法将字符串转换为小写
        String strLowerCase = "Hello World!".toLowerCase();
        System.out.println(strLowerCase); // 输出: hello world!

        // 使用format()方法格式化字符串
        String formattedString = String.format("The value of pi is %.2f", Math.PI);
        System.out.println(formattedString); // 输出: The value of pi is 3.14
    }
}

11. 字符串与 Stream API

  • chars() 可以将 String 类型转换为 IntStream 类型
  • mapToObj(c -> (char) c) 可以将 IntStream 类型转换为 Stream<Character> 类型
  • map(String::valueOf) 可以将 Stream<Character> 类型转换为Stream<String>类型
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Main {

    public static void main(String[] args) {
        // 案例1: 将字符串转换为字符流,并过滤出大写字母
        String str1 = "Hello World";
        List<Character> upperCaseChars = str1.chars()
                .mapToObj(c -> (char) c)
                .filter(c -> Character.isDigit(c)) //Character::isDigit
                .collect(Collectors.toList());
        System.out.println(upperCaseChars); // 输出: [H, W]

        // 案例2: 使用flatMap将字符串数组中的每个字符串拆分成字符流
        String[] strArray = {"abc", "def", "ghi"};
        List<Character> flatMapChars = Arrays.stream(strArray)
                .flatMap(s -> s.chars().mapToObj(c -> (char) c))
                .collect(Collectors.toList());
        System.out.println(flatMapChars); // 输出: [a, b, c, d, e, f, g, h, i]

        // 案例3: 将字符串分割成单词流,并过滤出长度大于4的单词
        String str2 = "This is an example sentence";
        List<String> longWords = Arrays.stream(str2.split(" "))
                .filter(s -> s.length() > 4)
                .collect(Collectors.toList());
        System.out.println(longWords); // 输出: [example, sentence]

        // 案例4: 将字符串转换为字符流,并按字母顺序排序
        String str3 = "dcba";
        String sortedStr = str3.chars()
                .mapToObj(c -> (char) c)
                .sorted()
                .map(String::valueOf)
                .collect(Collectors.joining());
        System.out.println(sortedStr); // 输出: abcd

        // 案例5: 使用map将字符串数组中的每个字符串转换为大写
        List<String> upperCaseStrings = Arrays.stream(strArray)
                .map(String::toUpperCase)
                .collect(Collectors.toList());
        System.out.println(upperCaseStrings); // 输出: [ABC, DEF, GHI]

        // 案例6: 计算字符串中元音字母的数量
        String str4 = "Apples and Oranges";
        long countVowels = str4.chars()
                .mapToObj(c -> (char) c)
                .filter(c -> "aeiouAEIOU".indexOf(c) != -1) // c in "aeiouAEIOU"
                .count();
        System.out.println(countVowels); // 输出: 5

        // 案例7: 检查字符串是否包含数字
        String str5 = "Java8";
        boolean containsDigit = str5.chars()
                .anyMatch(Character::isDigit);
        System.out.println(containsDigit); // 输出: true

        // 案例8: 使用limit和skip对流进行分页
        String str6 = "ABCDEFGHIJ";
        List<Character> paginatedChars = str6.chars()
                .mapToObj(c -> (char) c)
                .skip(5)
                .limit(3)
                .collect(Collectors.toList());
        System.out.println(paginatedChars); // 输出: [F, G, H]

        // 案例9: 使用distinct去除重复字符
        String str7 = "banana";
        String distinctChars = str7.chars()
                .distinct()
                .mapToObj(c -> (char) c)
                .map(String::valueOf)
                .collect(Collectors.joining());
        System.out.println(distinctChars); // 输出: ban

        // 案例10: 使用reduce将字符串数组中的所有字符串连接成一个字符串
        String joinedString = Arrays.stream(strArray) //strArray: {"abc", "def", "ghi"};
                .reduce("", (a, b) -> a.concat(b));
        System.out.println(String.join("", strArray)); //输出: abcdefghi
        System.out.println(joinedString); // 输出: abcdefghi
        
    }
}

二、StringBuilder

StringBuilder 是 Java 中的一个可变字符序列类。它提供了一系列方法用于高效地操作字符串。

1. 构造方法

  • StringBuilder(): 创建一个空的字符串构建器。
  • StringBuilder(CharSequence seq): 使用指定的序列创建一个字符串构建器。
  • StringBuilder(int capacity): 创建一个具有指定容量的字符串构建器。

2. 追加

  • StringBuilder append(String str): 将指定的字符串追加到此字符序列。
  • StringBuilder append(char c): 将指定的字符追加到此字符序列。

3. 插入

  • StringBuilder insert(int offset, String str): 将字符串插入到此字符序列中。
  • StringBuilder insert(int offset, char c): 将字符插入到此字符序列中。

4. 删除

  • StringBuilder delete(int start, int end): 删除此序列的子字符串中的字符。
  • StringBuilder deleteCharAt(int index): 删除此序列指定位置的字符。

5. 替换

  • StringBuilder replace(int start, int end, String str): 使用指定的字符串替换此序列的子字符串。

6. 反转

  • StringBuilder reverse(): 将此字符序列反转为相反的序列。

7. 其他方法

  • int length(): 返回长度(字符数)。
  • char charAt(int index): 返回指定索引处的字符。
  • StringBuilder setCharAt(int index, char ch): 将指定索引处的字符设置为指定字符。
  • String toString(): 返回此序列中数据的字符串表示形式。
public class Main {
    public static void main(String[] args) {
        // 创建StringBuilder实例
        StringBuilder sb = new StringBuilder("Hello");

        // 追加字符串
        sb.append(" World");
        System.out.println(sb); // 输出: Hello World

        // 追加字符
        sb.append('!');
        System.out.println(sb); // 输出: Hello World!

        // 插入字符串
        sb.insert(5, " Java");
        System.out.println(sb); // 输出: Hello Java World!

        // 插入字符
        sb.insert(10, ',');
        System.out.println(sb); // 输出: Hello Java, World!

        // 删除子字符串
        sb.delete(10, 15);
        System.out.println(sb); // 输出: Hello Java World!

        // 删除指定位置的字符
        sb.deleteCharAt(10); // 删除一个" "
        System.out.println(sb); // 输出: Hello JavaWorld!

        // 替换子字符串
        sb.replace(5, 9, "World");
        System.out.println(sb); // 输出: Hello World!

        // 反转字符串
        sb.reverse();
        System.out.println(sb); // 输出: !dlroW olleH

        // 获取长度
        System.out.println(sb.length()); // 输出: 12

        // 获取指定位置的字符
        System.out.println(sb.charAt(0)); // 输出: !

        // 设置指定位置的字符
        sb.setCharAt(0, 'H');
        System.out.println(sb); // 输出: HdlroW olleH

        // 转换为字符串
        String str = sb.toString();
        System.out.println(str); // 输出: HdlroW olleH
    }
}

8. StringBuilder和StringBuffer的区别

线程安全性:

  • StringBuilder是非线程安全的。这意味着在一个多线程环境中,如果有多个线程同时修改StringBuilder实例,那么它可能会导致数据不一致或者错误。
  • StringBuffer是线程安全的。它的所有公共方法都是同步的,确保在多线程环境中可以安全地使用而不会出现线程安全问题。

性能:

  • 由于StringBuilder不是线程安全的,它通常比StringBuffer更快,因为它不需要考虑线程同步的开销。
  • StringBuffer由于同步机制,其性能通常低于StringBuilder。

使用场景:

  • 如果正在编写单线程应用程序,或者不需要在多线程环境中共享字符串构建器实例,那么使用StringBuilder是更好的选择,因为它更高效。
  • 如果需要在多线程环境中操作字符串,或者需要确保字符串操作的原子性,那么应该使用StringBuffer。

历史:

  • StringBuffer是Java早期版本的一部分,随着Java的发展,为了提供更好的性能,后来引入了StringBuilder。

API:

  • StringBuilder和StringBuffer的API几乎相同,都提供了用于追加、插入、删除和替换字符串的方法。

9. String, StringBuilder和StringBuffer的执行速度对比

public class Main {
    public static void main(String[] args) {
        int iterations = 800000;
        String text = "a";

        // 测试 String
        long startTimeString = System.currentTimeMillis();
        String resultString = "";
        for (int i = 0; i < iterations; i++) {
            resultString += text;
        }
        long endTimeString = System.currentTimeMillis();

        System.out.println("String concatenation time: " + (endTimeString - startTimeString) + " ms");

        // 测试 StringBuilder
        startTimeString = System.currentTimeMillis();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < iterations; i++) {
            sb.append(text);
        }
        endTimeString = System.currentTimeMillis();
        System.out.println("StringBuilder append time: " + (endTimeString - startTimeString) + " ms");

        // 测试 StringBuffer
        startTimeString = System.currentTimeMillis();
        StringBuffer sbf = new StringBuffer();
        for (int i = 0; i < iterations; i++) {
            sbf.append(text);
        }
        endTimeString = System.currentTimeMillis();
        System.out.println("StringBuffer append time: " + (endTimeString - startTimeString) + " ms");
    }
}
String concatenation time: 26694 ms
StringBuilder append time: 10 ms
StringBuffer append time: 7 ms

三、练习

1. 将给定的字符串进行反转。

public class Main {
    public static void main(String[] args) {
        String str = "test String";
        String stringReversed = new StringBuilder(str).reverse().toString();
        System.out.println(stringReversed); //gnirtS tset
    }
}

2. 将给定的字符串重复n次。

public class Main {
    public static void main(String[] args) {
        String str = "test ";
        int n = 5;
        StringBuilder sb = new StringBuilder();
        for (int i = 1; i <= n; i++) {
            sb.append(str);
        }
        String ans = sb.toString();
        System.out.println(ans); //test test test test test 
    }
}

3. 删除给定字符串中的所有空格。

public class Main {
    public static void main(String[] args) {
        String str = "test test test test test";
        String replace = str.replace(" ", "");
        String s = str.replaceAll(" ", "");
        System.out.println(replace);  //testtesttesttesttest
        System.out.println(s);        //testtesttesttesttest
    }
}

4. 查找字符串中指定子串出现的次数。

public class Main {
    public static void main(String[] args) {
        String str = "ab ab ab ab";
        String subStr = "ab";
        int count = 0;
        int index = 0;
        // 从index开始,返回str第一次出现的位置
        while ((index = str.indexOf(subStr, index)) != -1) {
            index += subStr.length(); //移动到下一个位置
            count++;
        }

        System.out.println(count); // 输出:4
    }
}

5. 使用StringBuilder截取字符串的前6个字符。

public class Main {
    public static void main(String[] args) {

        String test = "This is a test";
        StringBuilder sb = new StringBuilder(test);
        String substring = sb.substring(0, 6);
        System.out.println(substring); //This i

    }
}

6. 使用StringBuilder反转字符串中的单词顺序,单词之间以单个空格分隔。如 "this is a test" 转换成 "test a is this"

public class Main {
    public static void main(String[] args) {
        String test = "this is a test";
        String[] strs = test.split(" ");
        StringBuilder sb = new StringBuilder();
        for (int i = strs.length - 1; i >= 0; i--) {
            sb.append(strs[i]).append(" ");
        }
        System.out.println(sb.toString().trim()); //test a is this
    }
}

7. 使用StringBuilder对字符串中的字符进行字典序排序。

import java.lang.reflect.Array;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        String test = "watermelon";
        char[] charArray = test.toCharArray();
        Arrays.sort(charArray);
        StringBuilder sb = new StringBuilder().append(charArray);
        System.out.println(sb.toString()); //aeelmnortw
    }
}

8. 将字符串中的每个单词首字母转换为大写。

import java.util.Arrays;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        String str = "this is a test";

        // 方法一
        String collect = Arrays.stream(str.split(" "))
                .map(s -> Character.toUpperCase(s.charAt(0)) + s.substring(1))
                .collect(Collectors.joining(" "));
        System.out.println(collect); //This Is A Test

        // 方法二
        String[] strArr = str.split(" ");
        StringBuilder sb = new StringBuilder();
        for (var i : strArr) {
            sb.append(Character.toUpperCase(i.charAt(0)))
                    .append(i.substring(1))
                    .append(" ");
        }
        System.out.println(sb.toString()); //This Is A Test
    }
}

9. 将字符串中连续的空格替换为单个空格。

public class Main {
    public static void main(String[] args) {
        String str = "this     is   \t a    test";
        String s = str.replaceAll("\\s+", " ");
        System.out.println(s); //this is a test

    }
}

10. 删除字符串中所有的指定字符。

import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        String str = "this is a test";
        char delChar = 's';

        // 方法一
        char[] charArray = str.toCharArray();
        StringBuilder sb = new StringBuilder();
        for(char c : charArray){
            if(c!=delChar){
                sb.append(c);
            }
        }
        System.out.println(sb.toString()); // thi i a tet


        // 方法二
        String collect = str.chars()
                .mapToObj(c -> (char) c)
                .filter(c -> c != delChar)
                .map(String::valueOf)
                .collect(Collectors.joining(""));
        System.out.println(collect);      // thi i a tet
        
    }
}

11. 去除字符串中所有重复的字符。

import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        String str = "this is a test";
        String collect = str.chars()
                .distinct()
                .mapToObj(a -> String.valueOf((char) a))
                .collect(Collectors.joining(""));
        System.out.println(collect); //this ae
    }
}

12. 判断一个字符串是否为回文。

public class Main {
    public static void main(String[] args) {
        String test = "abba2";
        StringBuilder sb = new StringBuilder(test);
        String reverse = sb.reverse().toString();
        if (test.equals(reverse)) {
            System.out.println("回文串");
        } else {
            System.out.println("不是回文串");
        }
    }
}

13. 统计字符串中每个字母出现的次数。

import java.util.Map;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        String test = "abbacccc";
        Map<String, Long> collect = test.chars()
                .mapToObj(s -> String.valueOf((char) s))
                .collect(Collectors.groupingBy(s -> s, Collectors.counting()));
        System.out.println(collect);
        
    }
}

14. 计算字符串中元音字母(a, e, i, o, u)的数量。

public class Main {
    public static void main(String[] args) {
        String test = "abbacccc";
        // 方法一
        int cnt = 0;
        for (int i = 0; i < test.length(); i++) {
            char c = test.charAt(i);
            if ("aeiou".indexOf(c) != -1) {
                cnt++;
            }
        }
        System.out.println(cnt);

        //方法二
        long count = test.chars()
                .mapToObj(c -> String.valueOf((char) c))
                .filter(s -> "aeiou".contains(s))
                .count();
        System.out.println(count);

    }
}

15. 使用StringBuilder将字符串中的每个单词长度缩短到k个字符(如果单词长度超过k),然后返回修改后的字符串。

public class Main {
    public static void main(String[] args) {
        String test = "This is a test";
        int k = 3;
        String[] s = test.split(" ");
        StringBuilder sb = new StringBuilder();
        for (String word : s) {
            sb.append(word.substring(0, Math.min(k, word.length()))).append(" ");
        }
        System.out.println(sb.toString().trim()); //Thi is a tes
    }
}

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值