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

Java字符串知多少:String、StringBuffer、StringBuilder

一、String

1、简介

  • String 是 Java 中使用得最频繁的一个类了,不管是作为开发者的业务使用,还是一些系统级别的字符使用, String 都发挥着重要的作用。
  • String 是不可变的、final的,不能被继承,且 Java 在运行时也保存了一个字符串池(String pool) ,就使得 String 变得很特殊。
  • 实现三个接口:java.io.Serializable, Comparable, CharSequence

2、String对象两种创建方法

// 1:编译时就确定了字符串的内容
String strComplier = "A";
// 2:new,只有运行时才能确定字符串的内容
String strNew = new String("A");
  • String strComplier = “A”;

Java 程序在运行的时候会维护着一个常量池,编译期生成的各种字面量和符号引用会在类加载后进入方法区的运行时常量池。对于上述这种实现字符串的方式就可以在编译的时候确定字符串的内容,因此这一行生成的内存结构就如下图。

在这里插入图片描述

不严谨的讲:虚拟机栈中的 strComplier 存储的就是 A 在常量池中的地址

  • String strNew = new String(“A”);

因为使用的 new 的方式,所以这句代码只有运行的时候才能确定字符串的内容。而对于 new 关键字,java 是将对象的实例数据存放上的,但是又因 String 常量池的存在,因此实际上在堆上的 String 对象的数据又指向了字符串常量池。

在这里插入图片描述

不严谨的讲:虚拟机栈中的 strNew 存储的就是 strNew 这个对象在堆内存的地址,而 strNew 中的字符串数据又指向了常量池中的 A

3、比较: == 和 equals()

  • ==

    比较两个对象的引用是否相等,也就是说比较两个地址是否相等

//true : 地址相同
String a = "A";
String a1 = "A";
System.out.println(a1 == a); //指向的都是 A 的地址,地址相同,返回的是 true
//false : 地址不同,在堆中是两个不同的对象,虽然指向常量池中的同一个值 A
String b = new String("A");
String b1 = new String("A");
System.out.println(b==b1);//分别指向的是在堆内存上的不同对象的地址,地址不同,返回的是 false
//false : 地址不同
String c = "A";
String c1 = new String("A");
System.out.println(c == c1);//一个指向常量池,一个指向堆,返回 false
//true : 地址相同
String d = "A";
String d1 = d; 
System.out.println(d == d1);//把d中的 常量池地址 赋给d1,返回 true
//true : 地址相同
String a = "A1";
String a1 = "A" + 1;//编译时已确定
System.out.println(a == a1);//true//false : 地址不同
String b = "A1";
String b1 = "A";
String b2 = b1 + 1;//编译时不确定
System.out.println(b == b2);//false

在这里插入图片描述

  • equals

    比较的两个对象是否相等,也就是说是同一个对象,在jvm堆内是惟一的

    String类对equals()方法进行了重写,只有值相等,才为true

//equals方法源码
public boolean equals(Object anObject) {//判断是否是相同对象if (this == anObject) {return true;}//判断anObject是否是String类型if (anObject instanceof String) {//        String aString = (String)anObject;//判断编码是否相同if (coder() == aString.coder()) {////比较两个字符串是否完全相等return isLatin1() ? StringLatin1.equals(value, aString.value)                : StringUTF16.equals(value, aString.value);}} return false;
}

在这里插入图片描述

String stringCompiler = "A";
String stringNew = new String("A");
StringBuilder stringBuilder = new StringBuilder("A");
StringBuffer stringBuffer = new StringBuffer("A");
//不是相同对象
System.out.println(stringCompiler == stringNew);  // false
//不是相同对象,但都是String类型,编码、字符值都相同
System.out.println(stringCompiler.equals(stringNew));  // true
//stringBuilder不是String类型
System.out.println(stringCompiler.equals(stringBuilder));  // false
//stringBuffer不是String类型
System.out.println(stringNew.equals(stringBuffer));   // false
比较==equals()
String s1 = new String(“java”);
String s2 = new String(“java”);
false
s1、s2在堆中是不同的对象,地址不同
虽然都指向了常量池中的’'java"
true
String类对equals()进行了重写
只要值相同,就返回true
String s1 = new String(“java”);
String s2 = s1;
true
同一对象,地址相同,值相同
true
同一对象,地址相同,值相同
String s1 = “java”;
String s2 = “java”;
true
编译时值已确定
指向常量池中同一地址
true
值相同

4、final

  • String 是 final ,也就是String 是不可变的。即一个 String 对象创建之后所有对它修改后的字符串,都是新生成的 String 对象。
  • String 设计成 final 主要有如下原因:
    • 实现字符串常量池,只有当字符串是不可变时字符串池才有可能实现,字符串池的实现可以在运行时节约很多 heap 空间,因为不同的字符串变量都指向池中的同一个字符串,即可以实现多个变量引用 JVM 内存中的同一个字符串实例,如果字符串不是不变的,String interning 将不能实现(String interning 是指对不同的字符串仅仅只保存一个,即不会保存多个相同的字符串),因为这样的话,如果变量改变了它的值,那么其它指向这个值的变量的值也会一起改变。
    • 安全问题,在系统中有很多地方都是以字符串的形式存在的,比如数据库的用户名,Socket 的主机和端口,当你在调用其他方法,比如调用一些系统级操作之前,可能会有一系列校验,如果是可变类的话,可能在你校验过后,其内部的值被改变了,可能引起严重的系统崩溃问题。
    • 缓存提升性能,String 大量运用在哈希的处理中,由于 String 的不可变性,可以只计算一次哈希值,然后缓存在内部,后续直接取就好了,字符串的处理速度要快过其它的键对象,这就是 HashMap 中的键往往都使用字符串的原因。
    • 线程安全,因为字符串是不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享。这样便不用因为线程安全问题而使用同步。

5、编码与解码

//编码
String.getBytes()//方法是得到一个操作系统默认的编码格式的字节数组。
String.getBytes(String decode)//方法会根据指定的decode编码返回某字符串在该编码下的byte数组表示//解码    
new String(byte[] b,String decode)//按照指定的方法编码
  • 示例
//编码解码一致,正确输出
byte[] b_gbk = "中".getBytes("GBK"); 
String s_gbk = new String(b_gbk,"GBK"); 
System.out.println(s_gbk);//中
//编码解码不一致,输出乱码
byte[] b_gbk = "中".getBytes("GBK"); 
String s_utf8 = new String(b_gbk,"UTF-8"); 
System.out.println(s_utf8);//��

二、StringBuffer

  • final,不能被继承,不能有子类
  • 线程安全
  • 通过append、insert进行字符串的操作
  • 实现接口:java.io.Serializable, CharSequence

三、StringBuilder

  • final,不能被继承,不能有子类
  • 线程不安全
  • 通过append、insert进行字符串的操作
  • 实现接口:java.io.Serializable, CharSequence

四、三者比较

比较StringStringBufferStringBuilder
继承性finalfinalfinal
实现接口Serializable
Comparable
CarSequence
Serializable
CarSequence
Serializable
CarSequence
速度
线程安全性线程安全线程安全线程不安全
常用方法equals()append()
insert()
append()
insert()
适用场景少量的字符串操作多线程下的大量操作单线程下的大量操作

相关文章:

Java字符串知多少:String、StringBuffer、StringBuilder

一、String 1、简介 String 是 Java 中使用得最频繁的一个类了,不管是作为开发者的业务使用,还是一些系统级别的字符使用, String 都发挥着重要的作用。String 是不可变的、final的,不能被继承,且 Java 在运行时也保…...

中国20强(上市)游戏公司2022年财报分析:营收结构优化,市场竞争进入白热化

易观:受全球经济增速下行的消极影响,2022年国内外游戏市场规模普遍下滑。但中国游戏公司凭借处于全球领先水平的研发、发行和运营的能力与经验,继续加大海外市场布局,推动高质量发展迈上新台阶。 风险提示:本文内容仅代…...

如何自学C++编程语言,聊聊C++的特点,别轻易踩坑

为什么现在有那么多C培训班呢?因为这些培训班可以为学生安排工作,而外包公司因为缺人,需要做很多项目,可能需要在全国各地分配不同的程序员去干不同的项目,因此需要大量的程序员入职。这样,外包公司就会找培…...

算法Day07 | 454.四数相加II,383. 赎金信,15. 三数之和, 18. 四数之和

Day07 454.四数相加II383. 赎金信15. 三数之和18. 四数之和 454.四数相加II 题目链接:454.四数相加II 寻找两个数组之和,是否与另外两个数组之和有特定的关系。 因为数值可能跨度太大,选择使用下标表示为对应的数值大小,会很浪费…...

ps抠图、抠头发去背景等

方法一:背景橡皮擦 一、很早之前我们使用的是魔术棒工具,但现在我们可以使用Photoshop 有内置的“背景橡皮擦” 步骤: 第1步:在Photoshop中打开需要修的图。 第2步:单击并按住工具栏…...

计算机组成原理基础练习题第一章

有些计算机将一部分软件永恒地存于只读存储器中,称之为() A.硬件    B.软件C.固件    D.辅助存储器输入、输出装置以及外界的辅助存储器称为() A.操作系统    B.存储器 C.主机      D.外围设备完整的计算机系…...

[PyTorch][chapter 34][池化层与采样]

前言: 这里主要讲解一下卷积神经网络中的池化层与采样 目录 DownSampleMax poolingavg poolingupsampleReLu 1: DownSample 下采样,间隔一定行或者列进行采样,达到降维效果 早期LeNet-5 就采样该采样方式。 LeNet-5 2 Max pooling 最大值采样…...

Java进阶-字符串的使用

1.API 1.1API概述 什么是API ​ API (Application Programming Interface) :应用程序编程接口 java中的API ​ 指的就是 JDK 中提供的各种功能的 Java类,这些类将底层的实现封装了起来,我们不需要关心这些类是如何实现的,只需要…...

接口自动化框架对比 | 质量工程

一、前言 自动化测试是把将手工驱动的测试行为转化为机器自动执行,通常操作是在某一框架下进行代码编写,实现用例自动发现与执行,托管在CI/CD平台上,通过条件触发或手工触发,进行回归测试&线上监控,代替…...

谷歌浏览器network error解决方法

很多用户在使用谷歌浏览器时候会出现network error网页提示,很多用户不知道该如何处理这一问题,其实解决方法不止一种,小编整理了两种谷歌浏览器network error解决方法,一起来看看吧~ 谷歌浏览器network error解决方法&#xff1…...

自动化测试如何做?接口自动化测试框架必备的9个功能,测试老鸟总结...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 当你准备使用一个…...

ANR原理篇 - ANR原理总览

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 文章目录 系列文章目录前言ANR流程概览ANR触发机制一、service超时机制二、broadcast超时机制三、provider超…...

新版Mamba体验超快的软件安装

在一文掌握Conda软件安装:虚拟环境、软件通道、加速solving、跨服务器迁移中详细介绍的conda的基本使用和遇到问题的解决方式,也提到了mamba作为一个替代工具,可以很好的加速conda的solving environemnt过程。但有时也会遇到一个很尴尬的问题…...

LDAP配置与安装

LDAP配置与安装 一、安装LDAP1、安装OpenLDAP及相关依赖包2、查看OpenLDAP版本3、配置OpenLDAP数据库4、设置OpenLDAP的管理员密码5、修改配置文件5.1. 修改{2}hdb.ldif文件5.2. 修改{1}monitor.ldif文件5.3. 修改{-1}frontend.ldif文件 6、验证LDAP的基本配置7、修改LDAP文件权…...

1-Linux环境安装JDK

Linux环境安装JDK 准备: ① Linux 环境 本文中Linux环境为 CentOS Linux 7 可使用以下命令查询 linux 系统版本: hostnamectl② 准备JDK包 进入官网 https://www.oracle.com/java/technologies/downloads/#java17下载对应jdk包 此处使用以前下载的旧…...

通胀数据回落助金价小幅回升

现货黄金窄幅震荡,目前交投于2032.92美元/盎司附近。隔夜美国通胀数据弱于市场预期,市场对美联储6月份加息预期降温,美元指数走弱,金价一度冲高至2050关口附近,不过,随后金价回吐全部涨幅,并一度…...

正则表达式的基本语法以及技巧和示例

正则表达式(Regular Expression)是一种强大的文本模式匹配工具,它使用特定的语法规则来描述和匹配字符串。在实际应用中,正则表达式可以用于搜索、替换、验证和分割文本数据。本文将详细解释正则表达式的语法和常用的使用示例。 …...

蓝牙耳机怎么挑选?小编分享2023畅销蓝牙耳机排行榜

蓝牙耳机怎么挑选?蓝牙、音质、续航、佩戴是蓝牙耳机选购时最重要的四大维度,这几年随着技术的成熟体验有了很大改善,但挑选的时候仍然要仔细对比,不然容易踩雷。小编根据销量整理了蓝牙耳机排行榜,一起看看最受消费者…...

Linux快照太有趣了!

1.首先介绍一下什么是Linux快照 VMware 的菜单栏中有虚拟机快照这个选项,形象来说快照就相当于一个备份文件,记录的是虚拟机运行到某一节点时的状态,在虚拟机的使用过程中如果发生了意外,比如系统崩溃或系统异常,此时…...

【改进粒子群优化算法】自适应惯性权重粒子群算法(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...

Java 加密常用的各种算法及其选择

在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 ​…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建

【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...

WebRTC调研

WebRTC是什么,为什么,如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...

boost::filesystem::path文件路径使用详解和示例

boost::filesystem::path 是 Boost 库中用于跨平台操作文件路径的类&#xff0c;封装了路径的拼接、分割、提取、判断等常用功能。下面是对它的使用详解&#xff0c;包括常用接口与完整示例。 1. 引入头文件与命名空间 #include <boost/filesystem.hpp> namespace fs b…...