Wrayの知识库 Wrayの知识库
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • MacOS
  • Linux
  • Windows
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • MacOS
  • Linux
  • Windows
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
  • Java基础

    • Java概述
    • Java语法
    • 面向对象编程
    • Java数组
    • String字符串
      • 字符串的特点
      • 字符串的创建
      • 字符串常用操作
      • 字符串的不可变性与 StringBuilder / StringBuffer
      • 常见的应用场景
      • Java字符串的常见问题
    • 异常处理
  • Java集合

    • Java集合概述
    • ArrayList
    • LinkedList
    • HashMap
    • LinkedHashMap
    • HashSet
    • TreeMap
    • Queue&Deque
  • Java并发

    • Java并发概述
    • 线程与进程
    • Thread类与线程生命周期
    • 线程安全
    • synchronized关键字
    • volatile关键字
    • Java内存模型(JMM)
    • 线程间通信
    • 线程池
    • 并发工具类
    • 原子操作类Atomic
    • 并发锁
    • 并发容器
    • ConcurrentHashMap
    • BlockingQueue
    • CopyOnWriteArrayList
    • ThreadLocal
    • Fork/Join框架
    • ScheduledThreadPoolExecutor
    • CompletableFuture
  • Java IO

    • Java IO概述
  • JVM

    • JVM概述
  • Java
  • Java基础
Wray
2024-10-31
目录

String字符串

在 Java 中,字符串 (String) 是最常用的数据类型之一,用于表示一系列字符。Java 中的字符串是不可变的,这意味着字符串一旦创建,其内容就不能被更改。字符串在 Java 中被设计为 String 类的对象,位于 java.lang 包中。

# 字符串的特点

  1. 不可变性:Java 的字符串是不可变对象,一旦创建就无法更改其值。如果需要修改字符串,系统会创建一个新的字符串对象来存储新的值。
  2. 字符串常量池:为了节约内存,Java 会将字符串字面量存储在一个称为“字符串常量池”的共享池中。如果两个字符串的值相同,它们会引用同一个内存地址。字符串常量池位于方法区(JDK 8 之前)或元空间(JDK 8 及之后)的内存中。
  3. 通过对象引用使用:String 是一个引用数据类型,而不是基本数据类型,所有字符串都是 String 类的对象。

# 字符串的创建

Java 提供了多种方式来创建字符串:

  • 使用字符串字面量:

    String greeting = "Hello, World!";
    

    使用字面量创建字符串会将其放入字符串常量池中,如果存在相同内容的字符串,就会引用已经存在的字符串对象。

  • 使用 new 关键字:

    String greeting = new String("Hello, World!");
    

    使用 new 关键字创建字符串时,会强制创建一个新的字符串对象,即使字符串常量池中已经存在相同内容的字符串。

# 字符串常用操作

Java 提供了丰富的方法来操作字符串,以下是一些常用操作:

  1. 获取字符串长度:使用 length() 方法。

    String str = "Java";
    int length = str.length(); // 返回 4
    
  2. 字符串拼接:使用 + 运算符或 concat() 方法。

    String firstName = "John";
    String lastName = "Doe";
    String fullName = firstName + " " + lastName; // 使用 + 进行拼接
    String fullName2 = firstName.concat(" ").concat(lastName); // 使用 concat() 方法
    
  3. 字符串比较:使用 equals() 方法或 equalsIgnoreCase() 方法。

    String str1 = "Hello";
    String str2 = "hello";
    boolean isEqual = str1.equals(str2); // 返回 false
    boolean isEqualIgnoreCase = str1.equalsIgnoreCase(str2); // 返回 true
    
  4. 查找字符或子串:使用 indexOf() 方法。

    String str = "Hello, World!";
    int index = str.indexOf("World"); // 返回 7
    
  5. 字符串替换:使用 replace() 方法。

    String str = "Hello, Java!";
    String replacedStr = str.replace("Java", "World"); // 返回 "Hello, World!"
    
  6. 子字符串提取:使用 substring() 方法。

    String str = "Hello, World!";
    String subStr = str.substring(7, 12); // 返回 "World"
    
  7. 转换大小写:使用 toUpperCase() 和 toLowerCase() 方法。

    String str = "Java";
    String upperStr = str.toUpperCase(); // 返回 "JAVA"
    String lowerStr = str.toLowerCase(); // 返回 "java"
    

# 字符串的不可变性与 StringBuilder / StringBuffer

由于字符串的不可变性,每次对字符串进行修改(例如拼接)都会创建一个新的对象,这样在频繁修改字符串时会导致大量内存开销。为了高效地处理可变字符串,Java 提供了两个可变的字符串类:

  1. StringBuilder:用于处理可变字符串,线程不安全,但效率高。

    StringBuilder sb = new StringBuilder("Hello");
    sb.append(", World!");
    String result = sb.toString(); // 返回 "Hello, World!"
    
  2. StringBuffer:与 StringBuilder 类似,但线程安全,适用于多线程环境。

    StringBuffer sb = new StringBuffer("Hello");
    sb.append(", World!");
    String result = sb.toString(); // 返回 "Hello, World!"
    

# 常见的应用场景

  1. 文本操作:String 用于存储和操作文本,如用户输入的数据、文件内容等。
  2. 频繁修改的字符串:对于频繁修改的字符串,建议使用 StringBuilder 或 StringBuffer,以提高性能。
  3. 连接和格式化:StringBuilder 在需要大量拼接字符串的场景中非常有用,例如生成 HTML 内容或 SQL 查询。

# Java字符串的常见问题

  1. 字符串比较错误

    • 在 Java 中,使用 == 来比较字符串时,比较的是两个字符串对象的引用,而不是它们的内容。因此,即使两个字符串具有相同的内容,== 也可能返回 false。
    • 正确的方法是使用 equals() 方法来比较字符串内容。
    String str1 = "Hello";
    String str2 = new String("Hello");
    System.out.println(str1 == str2); // 可能返回 false
    System.out.println(str1.equals(str2)); // 返回 true
    
  2. 字符串的不可变性导致性能问题

    • 由于字符串不可变,每次对字符串进行修改(如拼接)时,都会创建一个新的对象,这会导致大量内存开销,尤其是在循环中频繁修改字符串时。
    • 解决方法是使用 StringBuilder 或 StringBuffer,它们是可变的,适合在需要频繁修改字符串的场景中使用。
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 1000; i++) {
        sb.append(i);
    }
    
  3. 空指针异常 (NullPointerException)

    • 当调用字符串方法时,如果字符串为 null,则会抛出空指针异常。例如:
    String str = null;
    int length = str.length(); // 会抛出 NullPointerException
    
    • 解决方法是先检查字符串是否为 null,可以使用 if (str != null) 进行判断,或者使用 Objects.isNull() 方法。
  4. 字符串拼接的效率问题

    • 使用 + 运算符拼接字符串在编译时会转换为 StringBuilder 的操作,但如果在循环中频繁使用 + 拼接字符串,性能会很低,因为每次拼接都会创建新的对象。
    • 最佳做法是在循环中使用 StringBuilder,以避免不必要的对象创建和内存开销。
  5. 字符串常量池的使用和内存问题

    • 当使用字符串字面量时,字符串会存储在字符串常量池中。如果字符串数量较多,可能会占用大量内存。
    • 解决方法是尽量重用已有的字符串,而不是使用 new String() 创建新的字符串对象。
  6. 处理包含特殊字符的字符串

    • 在处理包含特殊字符(如换行符、引号等)的字符串时,需要使用转义字符:
    String str = "He said, \"Hello, World!\"";
    
    • 对于包含大量特殊字符的字符串,可以使用文本块(JDK 13+)来简化表示:
    String textBlock = """
    This is a text block
    that spans multiple lines
    """;
    
上次更新: 2024/10/31, 18:28:18
Java数组
异常处理

← Java数组 异常处理→

Copyright © 2023-2024 Wray | 鄂ICP备2024050235号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式