Day 5:字符串操作

理论知识:

1. String 的不可变性与常量池机制

  • 不可变性
    • String 对象一旦创建,其值无法更改。每次对字符串进行修改操作(如拼接、替换等)都会创建一个新的 String 对象。
public class StringImmutability {
    public static void main(String[] args) {
        String str1 = "hello";
        String str2 = str1.concat(" world");

        System.out.println("原始字符串: " + str1);  // 输出: hello
        System.out.println("新字符串: " + str2);  // 输出: hello world
    }
}
  • 常量池机制
    • Java 在常量池中缓存字符串字面量。对于相同内容的字符串字面量,只会在内存中存储一个实例。
public class StringPoolExample {
    public static void main(String[] args) {
        String str1 = "java";
        String str2 = "java";
        String str3 = new String("java");

        System.out.println(str1 == str2);  // 输出: true(指向同一个常量池对象)
        System.out.println(str1 == str3);  // 输出: false(指向堆中的新对象)
    }
}

2. StringBuilder 和 StringBuffer 的区别

  • StringBuilder
    • 线程不安全,但性能较高,适用于单线程环境。
  • StringBuffer
    • 线程安全,但性能稍低,适用于多线程环境。
public class StringBuilderVsStringBuffer {
    public static void main(String[] args) {
        long startTime, endTime;

        // StringBuilder 性能测试
        startTime = System.currentTimeMillis();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 100000; i++) {
            sb.append("a");
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuilder耗时: " + (endTime - startTime) + "ms");

        // StringBuffer 性能测试
        startTime = System.currentTimeMillis();
        StringBuffer sbf = new StringBuffer();
        for (int i = 0; i < 100000; i++) {
            sbf.append("a");
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuffer耗时: " + (endTime - startTime) + "ms");
    }
}

3. 常用字符串操作方法

  • 拼接
    • concat():直接连接两个字符串。
    • + 运算符:语法简洁,底层会自动使用 StringBuilder
public class StringConcatenation {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = "World";

        // 使用concat方法
        String result1 = str1.concat(" ").concat(str2);
        System.out.println("使用concat: " + result1);

        // 使用+运算符
        String result2 = str1 + " " + str2;
        System.out.println("使用+运算符: " + result2);
    }
}
  • 替换
    • replace():替换字符或子字符串。
public class StringReplaceExample {
    public static void main(String[] args) {
        String str = "apple, banana, cherry";

        // 替换所有逗号为分号
        String replacedStr = str.replace(",", ";");
        System.out.println("替换后的字符串: " + replacedStr);
    }
}
  • 查找与分割
    • indexOf():查找子字符串的位置。
    • split():按照指定分隔符拆分字符串。
public class StringSearchAndSplit {
    public static void main(String[] args) {
        String str = "Java is fun. Java is powerful.";

        // 查找子字符串的位置
        int index = str.indexOf("Java");
        System.out.println("第一次出现'Java'的位置: " + index);

        // 按空格分割字符串
        String[] words = str.split(" ");
        System.out.println("分割后的字符串数组:");
        for (String word : words) {
            System.out.println(word);
        }
    }
}

实践操作:字符串工具类

目标功能

  1. 统计字符串中每个字符的出现次数。
  2. 反转字符串。
  3. 替换指定字符。

代码实现

import java.util.HashMap;
import java.util.Map;

public class StringUtil {

    // 1. 统计字符出现次数
    public static Map<Character, Integer> countCharacterOccurrences(String str) {
        Map<Character, Integer> charCountMap = new HashMap<>();
        for (char c : str.toCharArray()) {
            charCountMap.put(c, charCountMap.getOrDefault(c, 0) + 1);
        }
        return charCountMap;
    }

    // 2. 反转字符串
    public static String reverseString(String str) {
        return new StringBuilder(str).reverse().toString();
    }

    // 3. 替换指定字符
    public static String replaceCharacter(String str, char oldChar, char newChar) {
        return str.replace(oldChar, newChar);
    }

    public static void main(String[] args) {
        String testString = "hello world";

        // 统计字符出现次数
        Map<Character, Integer> charCount = countCharacterOccurrences(testString);
        System.out.println("字符出现次数: " + charCount);

        // 字符串反转
        String reversed = reverseString(testString);
        System.out.println("反转后的字符串: " + reversed);

        // 替换指定字符
        String replacedString = replaceCharacter(testString, 'o', 'x');
        System.out.println("替换后的字符串: " + replacedString);
    }
}
public class Test {
    public static void main(String[] args) {
        /**
         * 这里给一个英语单词翻转的,这也是编程题的一道题。这个更多的时考察输入这部分吧
         * 例子输入:
         * 给定一句英语句子,每个单词之间可以有多个空格。句子首尾也可以有多个空格
         * | apple an is this |
         * 输出:
         * 翻转单词,去除多余的空格
         * |this is an apple|
         */
        String str = "apple an is this";
        String[] strs = str.split(" ");
        Object[] array = Arrays.stream(strs).toArray();
        for (int i = 0; i < array.length / 2; i++) {
            Object temp = array[i];
            array[i] = array[array.length - 1 - i];
            array[array.length - 1 - i] = temp;
        }
        String result = "";
        for (int i = 0; i < array.length; i++) {
            result += array[i] + " ";
        }
        System.out.println(result);
    }
}

工作中的使用场景

  • 日志分析:统计日志文件中字符、单词的出现次数。
  • 数据清洗:批量替换字符串中的特定字符或格式化数据。
  • 性能优化:在大量拼接操作中使用 StringBuilder 替代 String

总结

本文深入探讨了 Java 中字符串操作的相关知识和实践。首先,分析了 String 的不可变性及其在常量池中的优化机制,帮助开发者理解为什么 String 在内存中高效且安全。接着,对比了 StringBuilderStringBuffer,明确它们在单线程和多线程环境中的适用场景。然后,重点介绍了字符串的常用操作方法,如拼接、替换、查找与分割,并通过具体代码演示了它们的应用。最后,通过实践编写一个字符串工具类,将理论知识转化为实用功能,解决字符统计、字符串反转和字符替换等实际问题。这些知识在工作中能有效提高代码的性能和可读性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值