当前位置: 首页 > news >正文

黑马Java基础笔记-6

字符串

String

String的创建

1️⃣ 直接赋值法
 String name = "尼古拉斯·阿玮";  // 字面量直接初始化
2️⃣ 构造方法创建
构造方法核心功能说明
public String()创建空白字符串对象
public String(String original)克隆已有字符串对象
public String(char[] chs)将字符数组转为字符串
public String(byte[] chs)将字节数组解码为字符串(默认UTF-8)
例子
public class StringCreationDemo {public static void main(String[] args) {// 2.使用new的方式来获取一个字符串对象// 空参构造:可以获取一个空白的字符串对象String s2 = new String();System.out.println("\"" + s2 + "\"");// ""// 传递一个字符串,根据传递的字符串内容再创建一个新的字符串对象String s3 = new String("abc");System.out.println(s3);//abc// 传递一个字符数组,根据字符数组的内容再创建一个新的字符串对象// 需求:我要修改字符串的内容。 abc Qbc// abc --> {'a','b','c'} --> {'Q','b','c'} --> "Qbc"char[] chs = {'a','b','c','d'};String s4 = new String(chs);System.out.println(s4);//abcd// 传递一个字节数组,根据字节数组的内容再创建一个新的字符串对象// 应用场景:以后在网络当中传输的数据其实都是字节信息// 我们一般要把字节信息进行转换,转成字符串,此时就要用到这个构造了。byte[] bytes = {97, 98, 99, 100};String s5 = new String(bytes);System.out.println(s5);//abcd}
}
💡 重要特性对比
创建方式内存分配机制推荐使用场景
直接赋值复用字符串常量池对象已知字面量的字符串创建
new创建强制在堆中开辟新内存空间动态构建字符串内容
⚠️ 注意事项
  • 字面量方式创建的字符串会被字符串常量池缓存
  • new方式每次都会生成独立对象(即使内容相同)
  • 字节数组构造方法需注意字符编码一致性
  • 字符串不可改变,他的值一旦创建不可更改

String创建内存分析

直接赋值(省内存)

在这里插入图片描述

public class StringDemo {public static void main(String[] args) {String s1 = "abc";String s2 = "abc";}
}

当使用双引号直接赋值时,系统会检查该字符串在串池1中是否存在。

  • 不存在:创建新的
  • 存在:复用
new出来的

在这里插入图片描述

public class Test {public static void main(String[] args) {char[] chs = {'a', 'b', 'c'};String s1 = new String(chs);String s2 = new String(chs);}
}

String的比较

==比较

1. 基本数据类型(值比较)
int a = 10;
int b = 20;
System.out.println(a == b); //false

▶️ 直接比较变量存储的数值本身

2. 引用数据类型(地址比较)
String s1 = new String("abc");
String s2 = new String("abc"); 
System.out.println(s1 == s2); //false

▶️ 比较对象在内存中的存储地址

▶️ 即使对象内容相同,通过new创建会产生不同地址

▶️ 堆和串池中的地址值也不同

String s1 = new String("abc");//记录堆里面的地址值
String s2 = "abc";//记录串池中的地址值
System.out.println(s1== s2);//false

ps.Scanner获取的对象也是new出来的

比较

boolean  equals(要比较的字符串)								完全一样结果才是true,否则为false
boolean  equalslgnoreCase(要比较的字符串)				忽略大小写的比较

StringBuilder

StringBuilder 用于处理可变字符串,其内容可直接修改,不产生新对象,适用于频繁修改字符串的场景(如循环拼接、动态构建文本)。

底层原理

是一个字节数组byte[]

StringBuilder 的核心特性

  • 可变性:直接修改字符序列,无需创建新对象,内存效率高。
  • 非线程安全:方法没有用 synchronized 修饰,适用于单线程环境,性能高于 StringBuffer。
  • 链式调用:支持 append()insert()delete() 等方法链式调用。

初始容量与扩容

  • 默认初始容量为 16 个字符。最大容量为int最大值

  • 当字符数超过当前容量时,自动扩容:新容量 = 旧容量 * 2 + 2。

  • 如果一次要增加的长度超出了一次扩容的长度,就会以实际长度为准:

    比如要插入36个字符,容量为16*2+2=34小于36,则容量就会变为36

  • 底层核心代码如下:

int prefLength = oldLength + Math.max(minGrowth,prefGrowth);
//oldLength:旧容量
//minGrowth:需要新增的最小容量(count(原长度)+len(新增字符串的长度))-  oldLength
//prefGrowth:oldLength+2

StringBuilder vs String vs StringBuffer

特性StringStringBufferStringBuilder
可变性不可变可变可变
线程安全——安全(使用 synchronized)不安全
性能低(频繁修改时)
适用场景字符串常量、少量修改多线程环境下的字符串操作单线程环境下的字符串操作

核心方法及示例

初始化
// 默认容量 16
StringBuilder sb1 = new StringBuilder();// 指定初始容量
StringBuilder sb2 = new StringBuilder(100);// 从字符串初始化
StringBuilder sb3 = new StringBuilder("Hello");
追加内容(append)
StringBuilder sb = new StringBuilder();
sb.append("Java");       // 追加字符串
sb.append(2023);         // 追加整数
sb.append('!');          // 追加字符
System.out.println(sb);  // 输出 "Java2023!"
插入内容(insert)
sb.insert(4, " ");        // 在索引 4 处插入空格
System.out.println(sb);   // 输出 "Java 2023!"
删除内容(delete)
sb.delete(5, 9);          // 删除索引 5 到 8 的字符(左闭右开)
System.out.println(sb);   // 输出 "Java 3!"
替换内容(replace)
sb.replace(5, 6, "2024"); // 替换索引 5 到 5 的字符为 "2024"
System.out.println(sb);   // 输出 "Java 2024!"
反转字符串(reverse)
sb.reverse();
System.out.println(sb);   // 输出反转后的字符串,例如 "!4204 avaJ"
其他常用方法
方法功能描述
length()返回当前字符数
capacity()返回当前容量(可存储字符数)
setLength(int newLength)设置字符序列长度(截断或填充空字符)
charAt(int index)返回指定索引处的字符
substring(int start, int end)提取子字符串(左闭右开)
扩容机制与优化
  • 默认扩容逻辑:当字符数超过当前容量时,扩容公式为新容量 = 旧容量 * 2 + 2。 例如:初始容量 16 → 扩容后 34 → 再扩容 70 → …

  • 优化建议:如果预估最终字符串长度,建议初始化时指定容量以减少扩容次数。

    // 预估最终长度约为 1000 个字符
    StringBuilder sb = new StringBuilder(1000);
    

与 StringBuffer 的选择

  • 单线程环境:优先使用 StringBuilder(性能更高)。
  • 多线程环境:使用 StringBuffer(线程安全)。

综合示例

public class StringBuilderDemo {public static void main(String[] args) {// 初始化StringBuilder sb = new StringBuilder("Hello");// 追加内容sb.append(" World");System.out.println(sb); // 输出 "Hello World"// 插入内容sb.insert(5, ",");System.out.println(sb); // 输出 "Hello, World"// 替换内容sb.replace(6, 11, "Java");System.out.println(sb); // 输出 "Hello, Java"// 删除内容sb.delete(5, 7);System.out.println(sb); // 输出 "HelloJava"// 反转字符串sb.reverse();System.out.println(sb); // 输出反转后的字符串,如 "avaJolleH"}
}

总结

  • 核心用途:高效处理需要频繁修改的字符串。
  • 性能关键:避免中间对象的创建,减少内存开销。
  • 最佳实践
    • 在循环或动态构建文本时优先使用 StringBuilder。
    • 预估容量以减少扩容次数。
    • 单线程环境下使用 StringBuilder 替代 StringBuffer 以提升性能。

  1. StringTable(字符串常量池)在JDK7版本开始从方法区中挪到了堆内存 ↩︎

http://www.xdnf.cn/news/248653.html

相关文章:

  • 伽利略如何测量光速?一场跨越山头的失败实验
  • VBA数据结构深度解析:基础类型、自定义类型与数组操作指南
  • Dagster资产工厂实战:从Python到YAML配置的高效ETL流程
  • 408真题笔记
  • 第十三章:LLM 应用质量保证:评估体系、工具与实战
  • 深入解析三大查找算法:线性查找、二分查找与哈希查找的原理与应用
  • 进程(Process)和操作系统(Operation System)
  • ctfshow web入门 web46
  • 用spring-boot-maven-plugin打包成单个jar有哪些缺点优化方案
  • pandas读取Excel数据(.xlsx和.xls)到treeview
  • JavaScript如何实现类型判断?
  • C语言 指针(2)
  • spring-cloud-alibaba最新版本聚合项目创建
  • 机器学习Day15 LightGBM算法
  • 探秘数据结构:构建高效算法的灵魂密码
  • GD32F407单片机开发入门(二十二)红外避障传感器模块实战含源码
  • 项目经验不够被拒3次?
  • 电流测量 I/V转换
  • 前端vue3项目学习
  • python3基础
  • 数位 DP 的关键
  • ProCCD:复古CCD相机应用,重现经典胶片感
  • 2025年五一杯数学建模竞赛赛题浅析-助攻快速选题
  • 深入探讨宾馆一次性牙刷价格,市场价格区间差异大
  • esp32cam开发板的引脚使用和测试
  • 注册登录页面项目
  • dify+ollama+知识库 部署
  • 数字智慧方案6156丨智慧医联体信息化解决方案(50页PPT)(文末有下载方式)
  • 今天的python练习题
  • Spring AOP---面向切面编程由认识到使用