【详识JAVA语言】String类2

news2025/1/24 17:51:48

常用方法

字符串的不可变性

String是一种不可变对象. 字符串中的内容是不可改变。字符串不可被修改,是因为:

1. String类在设计时就是不可改变的,String类实现描述中已经说明了

以下来自JDK1.8中String类的部分实现:

String类中的字符实际保存在内部维护的value字符数组中,该图还可以看出:

1. String类被final修饰,表明该类不能被继承

2. value被修饰被final修饰,表明value自身的值不能改变,即不能引用其它字符数组,但是其引用空间中 的内容可以修改。

2. 所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象 

比如replace方法:

【纠正】网上有些人说:字符串不可变是因为其内部保存字符的数组被final修饰了,因此不能改变。 这种说法是错误的,不是因为String类自身,或者其内部value被final修饰而不能被修改。

final修饰类表明该类不想被继承,final修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内 容是可以修改的。 

public static void main(String[] args) {

final int array[] = {1,2,3,4,5};

array[0] = 100;

System.out.println(Arrays.toString(array)); 

// array = new int[]{4,5,6}; 

// 编译报错:Error:(19, 9) java: 无法为最终变量array分配值

}

 

为什么 String 要设计成不可变的?(不可变对象的好处是什么?) (选学)

1. 方便实现字符串对象池. 如果 String 可变, 那么对象池就需要考虑写时拷贝的问题了.

2. 不可变对象是线程安全的.

3. 不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中.

那如果想要修改字符串中内容,该如何操作呢?

字符串修改

注意:尽量避免直接对String类型对象进行修改,因为String类是不能修改的,所有的修改都会创建新对象,效率 非常低下。

public static void main(String[] args) {

String s = "hello";

s += " world";

System.out.println(s); // 输出:hello world

}

但是这种方式不推荐使用,因为其效率非常低,中间创建了好多临时对象。

public static void main(String[] args) {

long start = System.currentTimeMillis(); 

String s = ""; 

for(int i = 0; i < 10000; ++i){ 

s += i; 

} 

long end = System.currentTimeMillis(); 

System.out.println(end - start);

start = System.currentTimeMillis(); 

StringBuffer sbf = new StringBuffer(""); 

for(int i = 0; i < 10000; ++i){ 

sbf.append(i); 

} end = System.currentTimeMillis(); 

System.out.println(end - start);

start = System.currentTimeMillis(); 

StringBuilder sbd = new StringBuilder(); 

for(int i = 0; i < 10000; ++i){ 

sbd.append(i); 

} 

end = System.currentTimeMillis(); 

System.out.println(end - start);

}

可以看待在对String类进行修改时,效率是非常慢的,因此:尽量避免对String的直接需要,如果要修改建议尽量 使用StringBuffer或者StringBuilder。

b. 借助StringBuffer 和 StringBuilder

 StringBuilder和StringBuffer

StringBuilder的介绍

由于String的不可更改特性,为了方便字符串的修改,Java中又提供StringBuilder和StringBuffer类。这两个类大 部分功能是相同的,这里介绍 StringBuilder常用的一些方法。

方法

说明

StringBuff append(String str)

在尾部追加,相当于String的+=,可以追加:boolean、char、char[]、 double、float、int、long、Object、String、StringBuff的变量

char charAt(int index)

获取index位置的字符

int length()

获取字符串的长度

int capacity()

获取底层保存字符串空间总的大小

void ensureCapacity(intmininmumCapacity)

扩容

void setCharAt(int index, char ch)

将index位置的字符设置为ch

int indexOf(String str)

返回str第一次出现的位置

int indexOf(String str, int fromIndex)

从fromIndex位置开始查找str第一次出现的位置

int lastIndexOf(String str)

返回最后一次出现str的位置

int lastIndexOf(String str, intfromIndex)

从fromIndex位置开始找str最后一次出现的位置

StringBuff insert(int offset, String str)

在offset位置插入:八种基类类型 & String类型 & Object类型数据

StringBuffer deleteCharAt(int index)

删除index位置字符

StringBuffer delete(int start, int end)

删除[start, end)区间内的字符

StringBuffer replace(int start, int end,String str)

将[start, end)位置的字符替换为str

String substring(int start)

从start开始一直到末尾的字符以String的方式返回

String substring(int start,int end)

将[start, end)范围内的字符以String的方式返回

StringBuffer reverse()

反转字符串

String toString()

将所有字符按照String的方式返回

public static void main(String[] args) {

StringBuilder sb1 = new StringBuilder("hello"); 

StringBuilder sb2 = sb1;

// 追加:即尾插-->字符、字符串、整形数字 

sb1.append(' ');  // hello 

sb1.append("world");  // hello world 

sb1.append(123);  // hello world123 

System.out.println(sb1); // hello world123 

System.out.println(sb1 == sb2); // true 

System.out.println(sb1.charAt(0)); // 获取0号位上的字符 h 

System.out.println(sb1.length()); // 获取字符串的有效长度14 

System.out.println(sb1.capacity()); // 获取底层数组的总大小 

sb1.setCharAt(0, 'H'); // 设置任意位置的字符 Hello world123 

sb1.insert(0, "Hello world!!!"); // Hello world!!!Hello world123

System.out.println(sb1); 

System.out.println(sb1.indexOf("Hello")); // 获取Hello第一次出现的位置 

System.out.println(sb1.lastIndexOf("hello")); // 获取hello最后一次出现的位置 

sb1.deleteCharAt(0); // 删除首字符 

sb1.delete(0,5); // 删除[0, 5)范围内的字符

String str = sb1.substring(0, 5); 

System.out.println(str); 

sb1.reverse(); // 字符串逆转 

str = sb1.toString(); // 将StringBuffer以String的方式返回 

System.out.println(str);

// 截取[0, 5)区间中的字符以String的方式返回

}

从上述例子可以看出:String和StringBuilder最大的区别在于String的内容无法修改而StringBuilder的内容可以修改。频繁修改字符串的情况考虑使用StringBuilder。

注意:String和StringBuilder类不能直接转换。如果要想互相转换,可以采用如下原则:

String变为StringBuilder: 利用StringBuilder的构造方法或append()方法

StringBuilder变为String: 调用toString()方法。

 面试题

1. String、StringBuffer、StringBuilder的区别

String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.

StringBuffer与StringBuilder大部分功能是相似的

StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作

2. 以下总共创建了多少个String对象【前提不考虑常量池之前是否存在】

String str = new String("ab"); // 会创建多少个对象 
String str = new String("a") + new String("b"); // 会创建多少个对象

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2D/3D相机手眼标定总结

1. 九点标定 九点标定法的本质&#xff1a; 无需进行相机内参标定&#xff0c;只能识别x&#xff0c;y坐标&#xff0c;属于2D平面标定&#xff0c;在标定过程中z是未知的。 该算法的核心是仿射变换&#xff0c;即图像坐标系到机器人坐标系的2D仿射变换&#xff08;注意这里并不…

【python--比对两个列表获取列表中出现频率最高的词及频率】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;Python &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; python练习题 完整代码 完整代码 from collections import Counter from data_keywords import extract_…

【Linux】文件传输工具lrzsz的安装与使用

目录 一、关于lrzsz 二、安装lrzsz 三、lrzsz的说明及使用 1、上传命令rz 2、下载命令sz 一、关于lrzsz 在开发的过程中&#xff0c;经常遇到 需要在 Linux 和 Windows 之间上传下载文件的情况 这时&#xff0c;一般都是使用 FTP 或者 WinSCP 工具进行上传下载, 虽然也能…

SRIO—IP讲解及说明

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、SRIO IP 概述1.1 逻辑层1.1.1 I/O 端口(I/O Port)1.1.2 消息端口(Messaing Port)1.1.3 用户自定义端口(User-Defined Port)1.1.4 维护端口(Maintenance Port)1.2 缓冲层1.3 物理层…

python+django+vue房屋租赁系统 8gwmf

房屋租赁系统在设计与实施时&#xff0c;采取了模块性的设计理念&#xff0c;把相似的系统的功能整合到一个模组中&#xff0c;以增强内部的功能&#xff0c;减少各组件之间的联系&#xff0c;从而达到减少相互影响的目的。如房源信息、预约信息、求租信息模块等[12]。 管理员后…

java工程师面试简历模板,2024谈一下当下最合适的Java架构

前言 这些算法&#xff0c;都是小编一点一点看的大佬们的方法&#xff0c;自己积累的. 如果有什么描述的不对的地方还望大佬赐教 多交流才能进步&#xff0c;加油&#xff0c;冲冲冲&#xff01;&#xff01;&#xff01; 目录 一、冒泡排序 二、选择排序 三、插入排序 四、快速…

Redis中的RDB和AOF持久化机制(一)

Redis持久化 RDB快照(snapshot). 在默认情况下&#xff0c;Redis将内存数据库快照保存在名字为dump.rdb的二进制文件中.Redis可以进行设置,让它在"N秒内数据集至少有M个改动"这一条件被满足时&#xff0c;自动保存一次数据集。比如说&#xff0c;以下设置会让Redis…

软件测试需求分析如何编写?为什么要进行测试需求分析?

在软件开发的过程中&#xff0c;软件测试需求分析是至关重要的一个环节。测试需求分析是指对待测软件的需求进行全面细致的分析&#xff0c;明确软件测试的目标和范围&#xff0c;为测试活动的进行提供指导。通过对软件需求的详细分析&#xff0c;可以确保测试人员清楚了解软件…

配置与管理防火墙

配置与管理防火墙 1&#xff0c;概念&#xff1a;设置在不同网络或网络安全域之间的一系列部件的组合。 2&#xff0c;功能&#xff1a;保护内网中易手攻击的服务&#xff1b;控制内外网之间网络系统的访问&#xff1b;隐藏内网的IP地址及结构的细节&#xff0c;提高网络保护…

3月每日一题笔记

感谢我的好朋友的鼓励 3月4日 两种等价方式&#xff1f;都是错误的 ->加减中不能使用等价无穷小&#xff1f; ->不全面。 两项无穷小相减, 那么两项无穷小比值的极限不等于 1 时, 或者两项无穷小相加时, 其比值极限不等于 −1 时, 代数和差各项可以用等价无穷小替换 等…

基于springboot的海滨体育馆管理系统的设计与实现论文

摘 要 本基于Spring Boot的海滨体育馆管理系统设计目标是实现海滨体育馆的信息化管理&#xff0c;提高管理效率&#xff0c;使得海滨体育馆管理工作规范化、高效化。 本文重点阐述了海滨体育馆管理系统的开发过程&#xff0c;以实际运用为开发背景&#xff0c;基于Spring Boot…

LLM 系列——BERT——论文解读

一、概述 1、是什么 是单模态“小”语言模型&#xff0c;是一个“Bidirectional Encoder Representations fromTransformers”的缩写&#xff0c;是一个语言预训练模型&#xff0c;通过随机掩盖一些词&#xff0c;然后预测这些被遮盖的词来训练双向语言模型&#xff08;编码器…

7.使用os.Args或flag解析命令行参数

文章目录 一、os.Args二、flag包基本使用 Go语言内置的flag包实现了命令行参数的解析&#xff0c;flag包使得开发命令行工具更为简单。 一、os.Args 如果你只是简单的想要获取命令行参数&#xff0c;可以像下面的代码示例一样使用os.Args来获取命令行参数。 package mainimp…

彻底解析:企业为何必须采用CRM系统以及其五大作用

相关数据显示&#xff0c;CRM系统在欧美发达国家的普及程度高&#xff0c;超出80%的企业部署了CRM管理系统。然而在国内这个比例依然很小只有10几%&#xff0c;为什么企业需要CRM系统&#xff1f;因为CRM可以为公司实现线索管理、绩效管理、销售流程管理、市场营销管理以及数据…

【python开发】网络编程(下)

这里写目录标题 一、OSI7二、TCP和UDP协议&#xff08;一&#xff09;UDP和TCP示例代码1、UDP2、TCP &#xff08;二&#xff09;TCP三次握手和四次挥手 三、粘包1、实际案例12、实际案例23、实际案例3 四、阻塞和非阻塞五、IO多路复用 一、OSI7 在电脑和电脑之间进行数据传输…

Three.js--》探寻Cannon.js构建震撼的3D物理交互体验(二)

我们用three.js可以绘制出各种酷炫的画面&#xff0c;但是当我们想要一个更加真实的物理效果的话&#xff0c;这个时候我们就需要一个物理的库&#xff0c;接下来我们就讲解一下今天要学习的canon&#xff0c;它可以给我们提供一个更加真实的物理效果&#xff0c;像物体的张力、…

【center-loss 中心损失函数】 原理及程序解释(完)

文章目录 前言问题引出open-set问题抛出 解决方法softmax函数、softmax-loss函数解决代码&#xff08;center_loss.py&#xff09;原理程序解释 代码运用 如何梯度更新首先了解一下基本的梯度下降算法然后代码解释见下面train() 补充&#xff1a;外围知识&#xff08;models.py…

同步通信和异步通信(RabbitMq学习前篇)

MQ学习前篇 文章目录 MQ学习前篇1、同步和异步通讯1.1、同步通讯和异步通讯1.2、同步调用存在的问题1.3、异步调用方案1.4、异步通信的缺点 1、同步和异步通讯 学习mq之前&#xff0c;就要先知道同步通讯和异步通讯的区别。 1.1、同步通讯和异步通讯 同步通讯就像是打电话&am…

部署LVS集群之DR模式

直接路由模式----DR模式 理念&#xff1a; 直接路由&#xff08;是lvs的默认模式&#xff09; DR模式和隧道模式唯一的区别&#xff1a;dr模式这四台服务器在同一网段&#xff0c;隧道模式 &#xff1a;这四台服务器不在同一网段 客户端 ------->代理服务器------->真实…

Unity中关于继承ScriptableObject的类

在游戏中我们会经常看到一些.asset的配置文件&#xff0c;而这些文件就是用一个自定义的类去继承ScriptableObject来生成的。比如当前有一些零散特效需要预加载&#xff0c;这个时候我们可以声明一个类去保存这些零散特效对象的信息&#xff0c;然后统一读取加载。 代码&#…