当前位置: 首页 > 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…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

【机器视觉】单目测距——运动结构恢复

ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛&#xf…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...