Java 编码系列:String、StringBuilder 与包装类

引言

在 Java 开发中,字符串操作和基本数据类型的封装是日常编程中不可或缺的一部分。正确理解和使用 StringStringBuilder 以及包装类(如 IntegerDouble 等)不仅可以提高代码的可读性和性能,还能避免一些常见的陷阱。本文将深入探讨这些技术的底层原理,并结合大厂的最佳实践,帮助读者掌握这些核心概念。

1. String 类
1.1 基本概念

String 是 Java 中最常用的数据类型之一,用于表示不可变的字符序列。一旦创建了一个 String 对象,其内容就不能再改变。这使得 String 在多线程环境中非常安全,但也可能导致性能问题。

1.2 底层原理
  • 字符串常量池:Java 中的字符串常量池存储了所有字符串字面量和通过 intern() 方法获取的字符串。当创建一个新的 String 对象时,如果字符串常量池中已经存在相同的字符串,则直接返回池中的引用,否则创建新的对象并将其添加到池中。

    String str1 = "Hello";
    String str2 = "Hello";
    System.out.println(str1 == str2); // trueString str3 = new String("Hello");
    System.out.println(str1 == str3); // false
  • 不可变性String 对象的不可变性是由其内部实现保证的。String 类的 value 字段是一个 final 的字符数组,且没有提供修改该数组的方法。

    final char value[];
1.3 常见操作
  • 拼接字符串

    • 使用 + 运算符:在编译时,+ 运算符会被转换为 StringBuilder 或 StringBuffer 的 append 方法。
    • 使用 StringBuilder 或 StringBuffer:对于频繁的字符串拼接操作,推荐使用 StringBuilder(单线程)或 StringBuffer(多线程)。
    // 使用 + 运算符
    String result = "";
    for (int i = 0; i < 10000; i++) {result += "a";
    }// 使用 StringBuilder
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 10000; i++) {sb.append("a");
    }
    String result = sb.toString();
  • 比较字符串

    • 使用 ==:比较的是对象的引用。
    • 使用 equals 方法:比较的是字符串的内容。
    String str1 = "Hello";
    String str2 = "Hello";
    String str3 = new String("Hello");System.out.println(str1 == str2); // true
    System.out.println(str1 == str3); // false
    System.out.println(str1.equals(str3)); // true
  • 字符串格式化

    • 使用 String.format 方法:类似于 C 语言中的 printf 函数。
    String formatted = String.format("Hello, %s!", "World");
    System.out.println(formatted); // Hello, World!
1.4 最佳实践
  • 避免频繁创建 String 对象:由于 String 是不可变的,频繁创建新的 String 对象会导致内存浪费。

  • 使用 StringBuilderStringBuffer 进行字符串拼接:特别是当需要多次拼接字符串时,使用 StringBuilderStringBuffer 可以显著提高性能。

  • 使用 intern 方法减少内存占用:对于重复出现的字符串,可以使用 intern 方法将其放入字符串常量池,减少内存占用。

    String str1 = "Hello".intern();
    String str2 = "Hello".intern();
    System.out.println(str1 == str2); // true
2. StringBuilder 类
2.1 基本概念

StringBuilder 是一个可变的字符序列,用于高效地进行字符串拼接操作。与 String 不同,StringBuilder 的内容是可以改变的,因此在进行大量字符串拼接时,使用 StringBuilder 可以显著提高性能。

2.2 底层原理
  • 可变性StringBuilder 的内部实现是一个字符数组 char[],可以通过 append 方法动态地增加数组的长度。

  • 线程安全性StringBuilder 不是线程安全的,如果需要在多线程环境中用,可以考虑使用 StringBuffer

    private char[] value;
    private int count;
2.3 常见操作
  • 创建 StringBuilder 对象

    StringBuilder sb1 = new StringBuilder();
    StringBuilder sb2 = new StringBuilder("Hello");
  • 追加字符串

    StringBuilder sb = new StringBuilder("Hello");
    sb.append(", ");
    sb.append("World!");
    System.out.println(sb.toString()); // Hello, World!
  • 插入字符串

    StringBuilder sb = new StringBuilder("Hello, World!");
    sb.insert(7, "Beautiful ");
    System.out.println(sb.toString()); // Hello, Beautiful World!
  • 删除字符串

    StringBuilder sb = new StringBuilder("Hello, World!");
    sb.delete(7, 14);
    System.out.println(sb.toString()); // Hello, 
  • 反转字符串

    StringBuilder sb = new StringBuilder("Hello, World!");
    sb.reverse();
    System.out.println(sb.toString()); // !dlroW ,olleH
2.4 最佳实践
  • 初始化容量:在创建 StringBuilder 对象时,可以指定初始容量,以减少数组扩容的次数。

    StringBuilder sb = new StringBuilder(1000);
  • 使用 StringBuilder 替代 + 运算符:特别是在循环中进行字符串拼接时,使用 StringBuilder 可以显著提高性能。

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 10000; i++) {sb.append("a");
    }
    String result = sb.toString();
3. 包装类
3.1 基本概念

Java 提供了一系列的包装类,用于将基本数据类型封装成对象。常见的包装类包括 IntegerDoubleBoolean 等。包装类提供了许多有用的方法,可以方便地进行数值转换、比较等操作。

3.2 底层原理
  • 自动装箱与拆箱:Java 5 引入了自动装箱(autoboxing)和拆箱(unboxing)机制,简化了基本数据类型和包装类之间的转换。

    Integer a = 10; // 自动装箱
    int b = a; // 自动拆箱
  • 缓存机制:为了提高性能,Java 会在某些范围内缓存包装类对象。例如,Integer-128127 之间的值会被缓存。

    Integer a = 100;
    Integer b = 100;
    System.out.println(a == b); // trueInteger c = 128;
    Integer d = 128;
    System.out.println(c == d); // false
3.3 常见操作
  • 数值转换

    • 基本类型转包装类:使用构造函数或 valueOf 方法。
    Integer a = Integer.valueOf(10);
    Double b = Double.valueOf(3.14);
    • 包装类转基本类型:使用 intValuedoubleValue 等方法。
    Integer a = 10;
    int b = a.intValue();
  • 字符串转换

    • 字符串转包装类:使用 parseIntparseDouble 等方法。
    String str1 = "10";
    Integer a = Integer.parseInt(str1);String str2 = "3.14";
    Double b = Double.parseDouble(str2);
    • 包装类转字符串:使用 toString 方法。
    Integer a = 10;
    String str1 = a.toString();Double b = 3.14;
    String str2 = b.toString();
  • 比较

    • 使用 ==:比较的是对象的引用。
    • 使用 equals 方法:比较的是对象的内容。
    Integer a = 100;
    Integer b = 100;
    System.out.println(a == b); // trueInteger c = 128;
    Integer d = 128;
    System.out.println(c == d); // falseSystem.out.println(a.equals(b)); // true
    System.out.println(c.equals(d)); // true
3.4 最佳实践
  • 避免不必要的装箱与拆箱:频繁的装箱与拆箱操作会影响性能,尽量使用基本数据类型。

  • 使用 valueOf 方法代替构造函数valueOf 方法会利用缓存机制,提高性能。

    Integer a = Integer.valueOf(10); // 推荐
    Integer b = new Integer(10); // 不推荐
  • 注意缓存范围:在使用 == 比较包装类对象时,要注意缓存范围的影响。

    Integer a = 100;
    Integer b = 100;
    System.out.println(a == b); // trueInteger c = 128;
    Integer d = 128;
    System.out.println(c == d); // false
4. 大厂最佳实践
4.1 字符串处理
  • 阿里巴巴《Java开发手册》
    • 避免使用 + 运算符进行字符串拼接:特别是在循环中,使用 StringBuilder 或 StringBuffer 可以显著提高性能。
    • 使用 String.format 方法进行字符串格式化:提高代码的可读性和维护性。
4.2 包装类使用
  • Google Java Style Guide
    • 避免使用 null 作为参数或返回值:使用 Optional 类来表示可能为空的值。
    • 使用 valueOf 方法代替构造函数:利用缓存机制提高性能。
4.3 性能优化
  • Oracle 官方文档
    • 初始化 StringBuilder 的容量:减少数组扩容的次数,提高性能。
    • 使用 intern 方法减少内存占用:对于重复出现的字符串,使用 intern 方法可以减少内存占用。
5. 总结

本文深入探讨了 Java 中的 StringStringBuilder 和包装类的底层原理,并结合大厂的最佳实践,帮助读者掌握这些核心概念。正确理解和使用这些技术不仅可以提高代码的可读性和性能,还能避免一些常见的陷阱。希望本文对你有所帮助,如果你有任何问题或建议,欢迎留言交流。


希望这篇文章能够满足你的需求,如果有任何进一步的问题或需要更多内容,请随时告诉我!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/428972.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2023北华大学程序设计新生赛部分题解

时光如流水般逝去&#xff0c;我已在校园中奋战大二&#xff01;(≧▽≦) 今天&#xff0c;静静回顾去年的新生赛&#xff0c;心中涌起无尽感慨&#xff0c;仿佛那段青春岁月如烟花般绚烂。✧&#xff61;(≧▽≦)&#xff61;✧ 青春就像一场燃烧的盛宴&#xff0c;激情澎湃&…

DOS(Disk Operating System,磁盘操作系统)常用指令

目录 背景: 早期探索: DOS之父&#xff1a; 发展历程&#xff1a; 常用指令&#xff1a; 进入命令&#xff1a; 操作1.进入和回退&#xff1a; 操作2.增、删&#xff1a; 操作3.其它&#xff1a; 总结: 背景: 早期探索: DOS(Disk Operating System,磁盘操作系统)在…

数据结构——二叉搜索树

目录 二叉搜索树 概念性质 性能分析 实现代码 前置准备 插入 查找 删除&#xff08;重点&#xff09; ​编辑 key和key/value的使用场景 key/value二叉搜索树代码实现 二叉搜索树 概念性质 二叉搜索树&#xff08;Binary Search Tree&#xff0c;简称BST&#xff0…

主流卷积神经网络CNN总结

ResNet&#xff08;2015&#xff09;残差神经网络 残差结构 ResNet50具体卷积结构图 ResNeXt&#xff08;2016&#xff09;加入了分组卷积的思想&#xff0c;将原ResNet网络中的block替换成由group分组的block&#xff0c;两者得到的feature map一致&#xff0c;只是参数量更少…

2024年华为杯-研赛F题论文问题一二讲解+代码分享

X射线脉冲星光子到达时间建模 摘要 脉冲星是一类高速自转的中子星&#xff0c;其自转形成规律性脉冲信号&#xff0c;类似于“宇宙中的灯塔”&#xff0c;因此被认为是极为精确的时钟。X射线脉冲星导航利用脉冲星信号为航天器提供时间和空间参考。通过比较脉冲信号到达航天器…

Vue3.0组合式API:使用reactive()、ref()创建响应式代理对象

Vue3.0组合式API系列文章&#xff1a; 《Vue3.0组合式API&#xff1a;setup()函数》 《Vue3.0组合式API&#xff1a;使用reactive()、ref()创建响应式代理对象》 《Vue3.0组合式API&#xff1a;computed计算属性、watch监听器、watchEffect高级监听器》 《Vue3.0组合式API&…

内网渗透之中间人欺骗攻击-ARP攻击

ARP攻击 ARP协议简介 ARP全称为Address Resolution Protocol&#xff0c;即地址解析协议&#xff0c;它是一个根据IP地址获取物理地址的TCP/IP协议&#xff0c;主机发送信息时将包含目标IP地址的ARP请求广播到网络上的所有主机&#xff0c;并接收返回消息&#xff0c;以此确定…

动态线程池(五)

动态线程池 Filter过滤器 AlarmBaseFilter NoticeBaseFilter NotifyRedisTateLimiterFilter RedisRateLimiter redis限流器 NotifierHandler DtpNotifier动态线程池通知者 Notifier通知者 关于发送Email消息的额外说明

【Java集合】深入了解ArrayList实现原理

概述 1.数据存储是基于动态数组实现的&#xff0c;默认初始容量为10。 2.添加数据时&#xff0c;首先需要检查元素个数是否超过数组容量&#xff0c;如果超过了则需要对数组进行扩容&#xff08;1.5倍&#xff09;&#xff1b;插入数据时&#xff0c;需要将从插入点 k 开始到数…

4.接口测试基础(Jmter工具/场景二:一个项目由多个人负责接口测试,我只负责其中三个模块,协同)

一、场景二&#xff1a;一个项目由多个人负责接口测试&#xff0c;我只负责其中三个模块&#xff0c;协同 1.什么是测试片段&#xff1f; 1&#xff09;就相当于只是项目的一部分用例&#xff0c;不能单独运行&#xff0c;必须要和控制器&#xff08;include,模块&#xff09;一…

河鱼浏览器——您的电商多店管理专家,轻松应对拼多多20+店铺登录挑战

在电商领域驰骋&#xff0c;每一个店铺都是您商业版图的一部分&#xff0c;但同时管理多个拼多多店铺&#xff0c;尤其是超过20个&#xff0c;是否让您感到力不从心&#xff1f;河鱼浏览器&#xff0c;专为电商精英打造的高效管理工具&#xff0c;为您化解这一难题。 **多开无…

JVM 一个对象是否已经死亡?

目录 前言 引用计数法 可达性分析法 引用 finalize() 方法区回收 前言 虚拟机中垃圾回收器是掌握对象生死的判官, 只要是垃圾回收器认为需要被回收的, 那么这个对象基本可以宣告"死亡". 但是也不是所有的对象, 都需要被回收, 因此, 我们在学习垃圾回收的时候…

Qt开发技巧(四)“tr“使用,时间类使用,Qt容器取值,类对象的删除,QPainter画家类,QString的转换,用好 QVariant类型

继续讲一些Qt技巧操作 1.非必要不用"tr" 如果程序运行场景确定是某一固定语言&#xff0c;就不需要用tr,"tr"之主要针对多语种翻译的&#xff0c;因为tr的本意是包含英文&#xff0c;然后翻译到其他语言比如中文&#xff0c;不要滥用tr&#xff0c;如果没有…

万字长文——ConvNeXt(2022CVPR),卷积网络的顶峰之作,在Transformer盛行的当下,卷积网络还能再战!

ConvNext:A ConvNet for the 2020s ConvNext:2020 年代的卷积神经网络 论文地址: https://arxiv.org/pdf/2201.03545 自从Transformer成功应用在视觉领域并且取得显著成绩后,很多人开始抛弃卷积网络架构,转而使用Transformer。然而有的大佬不认为卷积过时了,于是有了这篇…

OpenGL渲染管线(Rendering Pipeline)介绍

渲染管线 计算机图形学中&#xff0c;计算机图形管线&#xff08;渲染管线 或简称 图形管线、流水线&#xff09;是一个概念模型&#xff0c;它描述了t图像系统将 3D场景渲染到2D屏幕所需执行的一系列步骤。渲染管线大的可以分为三个阶段。 &#xff08;一&#xff09;应用阶段…

Web接入Sonic平台之安装

问题及解决方案 1.安装python的airtest-bdd依赖时报错&#xff0c;显示无法编译psutil note: This error originates from a subprocess, and is likely not a problem with pip. ERROR: Failed building wheel for psutil Failed to build psutil ERROR: ERROR: Failed to b…

Android SystemUI组件(07)锁屏KeyguardViewMediator分析

该系列文章总纲链接&#xff1a;专题分纲目录 Android SystemUI组件 本章关键点总结 & 说明&#xff1a; 说明&#xff1a;本章节持续迭代之前章节的思维导图&#xff0c;主要关注左侧上方锁屏分析部分即可。 为了更好理解本文的内容&#xff0c;优先说明下SystemUI中与Ke…

[已更新前两问代码+全部建模]2024华为杯C题详细思路代码文章建模分享研究生数学建模竞赛数学建模研赛

截止9.21 12点 已更新问题一二的代码和全部内容的建模 下面我们会先进行代码讲解,之后给出全部内容的建模公式 ## https://docs.qq.com/doc/DVWhyZ1NFY01XcmNw基于磁通密度数据的特征提取与分类分析。 问题一代码详解 1. 导入必要的库 import pandas as pd import numpy as…

Elastic 的 OpenTelemetry PHP 发行版简介

作者&#xff1a;Pawel Filipczak 宣布 OpenTelemetry PHP 的 Elastic 发行版的第一个 alpha 版本。在本篇博文中了解使用 OpenTelemetry 来检测 PHP 应用程序是多么简单。 我们很高兴推出 OpenTelemetry PHP 的 Elastic Distribution 的第一个 alpha 版本。在这篇文章中&…

十九、石英晶体振荡电路

石英晶体振荡电路 1、石英晶体的特点、等效电路、特性曲线; 2、石英晶体振动器的特点&#xff0c; 3、石英晶体振动器的振荡频率