学习Java26天

1. String 概述

核心概念

  • Java API:Java 提供的一套预定义类和接口,可以直接使用

  • String 类java.lang.String 代表字符串,程序中所有字符串字面值都是该类的对象

  • 重要特性 :String 对象是不可变的(immutable),创建后内容不能修改

2. 创建 String 对象的四种方式

方式1:直接赋值(最常用)

java

复制代码
// 语法:String 变量名 = "字符串内容";
String str1 = "Hello World";
String str2 = "Java";
String emptyStr = "";  // 空字符串

// 特点:会检查字符串池,如果已存在则复用
String s1 = "abc";
String s2 = "abc";  // s1 和 s2 指向同一个对象
System.out.println(s1 == s2);  // true,地址相同

方式2:new String() 构造方法

java

复制代码
// 1. 创建空白字符串
String str1 = new String();  // 等价于 ""
System.out.println(str1);  // 输出:空字符串
System.out.println(str1.length());  // 输出:0

// 2. 根据已有字符串创建
String original = "Hello";
String str2 = new String(original);  // 创建新的String对象,内容为"Hello"

// 3. 根据字符数组创建
char[] charArray = {'J', 'a', 'v', 'a'};
String str3 = new String(charArray);  // "Java"
String str4 = new String(charArray, 0, 2);  // 从索引0开始取2个字符:"Ja"

// 4. 根据字节数组创建(常用于网络传输、文件读写)
byte[] byteArray = {65, 66, 67, 68};  // ASCII: A, B, C, D
String str5 = new String(byteArray);  // "ABCD"

// 指定字符集
try {
    byte[] bytes = "你好".getBytes("UTF-8");
    String str6 = new String(bytes, "UTF-8");  // "你好"
} catch (Exception e) {
    e.printStackTrace();
}

3. String 类的常用方法

长度和空值判断

java

复制代码
String str = "Hello Java";

// 获取长度
int length = str.length();  // 10

// 判断是否为空
boolean isEmpty = str.isEmpty();  // false
boolean isEmpty2 = "".isEmpty();  // true

// 判断是否为空白(包含空格、制表符等)
boolean isBlank = "   ".isBlank();  // true(Java 11+)

字符串比较

java

复制代码
String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
String s4 = "ABC";

// 使用 == 比较(比较地址)
System.out.println(s1 == s2);  // true
System.out.println(s1 == s3);  // false(s3在堆内存中)

// 使用 equals() 比较(比较内容)
System.out.println(s1.equals(s2));  // true
System.out.println(s1.equals(s3));  // true
System.out.println(s1.equals(s4));  // false(区分大小写)

// 忽略大小写比较
System.out.println(s1.equalsIgnoreCase(s4));  // true

// 比较字符串字典顺序
System.out.println("abc".compareTo("abd"));   // -1(小于)
System.out.println("abc".compareTo("abc"));   // 0(等于)
System.out.println("abd".compareTo("abc"));   // 1(大于)

字符串查找

java

复制代码
String str = "Hello Java World";

// 查找字符/字符串位置
int index1 = str.indexOf('J');     // 6(第一个J的位置)
int index2 = str.indexOf("Java");  // 6
int index3 = str.indexOf('a', 7);  // 8(从索引7开始查找)

// 从后往前查找
int lastIndex = str.lastIndexOf('o');  // 13

// 是否包含
boolean contains = str.contains("Java");  // true

// 是否以指定字符串开始/结束
boolean startsWith = str.startsWith("Hello");  // true
boolean endsWith = str.endsWith("World");      // true

字符串截取和替换

java

复制代码
String str = "Hello Java World";

// 截取子串
String sub1 = str.substring(6);      // "Java World"(从索引6到结尾)
String sub2 = str.substring(6, 10);  // "Java"(从6到9,不包含10)

// 替换
String replaced1 = str.replace('o', 'O');  // "HellO Java WOrld"
String replaced2 = str.replace("Java", "Python");  // "Hello Python World"

// 替换所有(正则表达式)
String replaced3 = str.replaceAll("\\s+", "-");  // 将所有空白替换为-

字符串分割和连接

java

复制代码
// 分割字符串
String str = "apple,banana,orange";
String[] fruits = str.split(",");  // ["apple", "banana", "orange"]

// 复杂分割(正则表达式)
String complex = "apple, banana; orange";
String[] result = complex.split("[,\\s;]+");  // 按逗号、空格、分号分割

// 连接字符串
String joined = String.join("-", "Java", "Python", "C++");  // "Java-Python-C++"

大小写转换和去除空白

java

复制代码
String str = "  Hello Java  ";

// 大小写转换
String upper = str.toUpperCase();  // "  HELLO JAVA  "
String lower = str.toLowerCase();  // "  hello java  "

// 去除首尾空白
String trimmed = str.trim();       // "Hello Java"

// 去除首尾空白(包含Unicode空白符)
String stripped = str.strip();     // "Hello Java"(Java 11+)

其他常用方法

java

复制代码
String str = "Java";

// 获取指定位置的字符
char ch = str.charAt(2);  // 'v'

// 转换为字符数组
char[] chars = str.toCharArray();  // ['J', 'a', 'v', 'a']

// 转换为字节数组
byte[] bytes = str.getBytes();  // 使用平台默认编码

// 格式化字符串
String formatted = String.format("姓名:%s,年龄:%d", "张三", 25);

// 重复字符串
String repeated = "Java ".repeat(3);  // "Java Java Java "(Java 11+)

4. String 的不可变性

不可变性的表现

java

复制代码
String s1 = "Hello";
String s2 = s1;  // s1和s2指向同一个对象

s1 = s1 + " World";  // 创建新的String对象
System.out.println(s1);  // "Hello World"
System.out.println(s2);  // "Hello"(s2不受影响)

不可变性的好处

  1. 线程安全:无需同步

  2. 缓存哈希值:提高性能

  3. 字符串池:节省内存

  4. 安全性:防止被修改

5. 字符串常量池

内存机制

java

复制代码
// 情况1:直接赋值(使用常量池)
String s1 = "abc";  // 检查常量池,如果不存在则创建
String s2 = "abc";  // 复用常量池中的对象
System.out.println(s1 == s2);  // true

// 情况2:new String()(在堆内存创建新对象)
String s3 = new String("abc");
String s4 = new String("abc");
System.out.println(s3 == s4);  // false
System.out.println(s1 == s3);  // false

// 情况3:intern()方法(手动入池)
String s5 = s3.intern();  // 将s3的内容放入常量池
System.out.println(s1 == s5);  // true

6. 性能优化建议

避免使用 + 连接大量字符串

java

复制代码
// 错误做法(创建多个临时对象)
String result = "";
for (int i = 0; i < 1000; i++) {
    result += i;  // 每次循环创建新的String对象
}

// 正确做法(使用StringBuilder)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i);
}
String result = sb.toString();

7. 实际应用示例

示例1:用户输入验证

java

复制代码
import java.util.Scanner;

public class StringDemo {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        System.out.print("请输入用户名:");
        String username = scanner.nextLine().trim();
        
        // 验证用户名
        if (username.isEmpty()) {
            System.out.println("用户名不能为空!");
        } else if (username.length() < 3) {
            System.out.println("用户名至少3个字符!");
        } else if (!username.matches("[a-zA-Z0-9_]+")) {
            System.out.println("用户名只能包含字母、数字和下划线!");
        } else {
            System.out.println("用户名有效:" + username);
        }
    }
}

示例2:文件路径处理

java

复制代码
public class FilePathDemo {
    public static void main(String[] args) {
        String filePath = "C:/Users/User/Documents/test.txt";
        
        // 获取文件名
        int lastSlash = filePath.lastIndexOf('/');
        String fileName = filePath.substring(lastSlash + 1);
        System.out.println("文件名:" + fileName);  // test.txt
        
        // 获取文件扩展名
        int dotIndex = fileName.lastIndexOf('.');
        if (dotIndex > 0) {
            String extension = fileName.substring(dotIndex + 1);
            System.out.println("扩展名:" + extension);  // txt
        }
        
        // 获取文件路径
        String directory = filePath.substring(0, lastSlash);
        System.out.println("目录:" + directory);  // C:/Users/User/Documents
    }
}
相关推荐
cike_y5 小时前
JSP原理详解
java·开发语言·jsp
invicinble5 小时前
关于springboot引入traceid来保障可观测型
java·spring boot·后端
爱装代码的小瓶子6 小时前
【cpp进阶】c++11的新特性(概述版)
开发语言·c++
_OP_CHEN6 小时前
【从零开始的Qt开发指南】(十一)Qt常用控件之多元素控件与容器类控件深度解析
开发语言·qt·前端开发·多元素控件·gui开发·qt常用控件·容器类控件
Robot侠6 小时前
视觉语言导航从入门到精通(二)
开发语言·人工智能·python·llm·vln
SmoothSailingT6 小时前
C#——Lazy<T>懒加载机制
开发语言·单例模式·c#·懒加载
精神病不行计算机不上班6 小时前
[Java Web]在IDEA中完整实现Servlet的示例
java·servlet·tomcat·html·intellij-idea·web
chushiyunen6 小时前
javadoc规范、idea生成javadoc等
java·ide
小羊学伽瓦6 小时前
ThreadLocal
java·jvm·算法