技术总结(十四)

一、String、StringBuffer、StringBuilder的区别?

可变性

String 是不可变的(后面会详细分析原因)。

StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder 中也是使用字符数组保存字符串,不过没有使用 final 和 private 关键字修饰,最关键的是这个 AbstractStringBuilder 类还提供了很多修改字符串的方法比如 append 方法。


abstract class AbstractStringBuilder implements Appendable, CharSequence {char[] value;public AbstractStringBuilder append(String str) {if (str == null)return appendNull();int len = str.length();ensureCapacityInternal(count + len);str.getChars(0, len, value, count);count += len;return this;}
}


线程安全性

String 中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilder 是 StringBuilder 与 StringBuffer 的公共父类,定义了一些字符串的基本操作,如 expandCapacity、append、insert、indexOf 等公共方法。StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。

性能

每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象。StringBuffer 每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用 StringBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。

对于三者使用的总结:

操作少量的数据: 适用 String
单线程操作字符串缓冲区下操作大量数据: 适用 StringBuilder
多线程操作字符串缓冲区下操作大量数据: 适用 StringBuffer

二、在什么情况下使用String,什么情况下使用StringBuffer和StringBuilder?

  1. 使用 String 的情况
    • 字符串常量表示:当表示不会被修改的字符串常量时,应该使用String。例如,定义一个表示程序版本号的字符串:
     String version = "1.0.0";
  • 少量字符串拼接操作(在 Java 编译器优化下):对于一些简单的、少量的字符串拼接,Java 编译器会进行优化,使用String也可以。例如:
     String name = "John";String greeting = "Hello, " + name;

在这种情况下,Java 编译器可能会将其优化为一个StringBuilder的操作(在字节码层面),所以对于这种简单的拼接场景,使用String是可以的。

  • 方法参数传递和返回值(不需要修改的情况):当把字符串作为参数传递给一个方法,并且这个方法不会修改字符串内容,或者方法的返回值是一个不会被修改的字符串时,使用String。例如:
     public class StringUsage {public static void printString(String str) {System.out.println(str);}public static String getString() {return "This is a sample string";}}
  1. 使用 StringBuffer 的情况
    • 多线程环境下的字符串修改操作:在多线程环境中,如果多个线程需要对同一个字符串进行修改,就需要使用StringBuffer来保证线程安全。例如,一个简单的日志记录类,多个线程可能会同时向日志中添加内容:
     import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class StringBufferInMultiThread {private static StringBuffer logBuffer = new StringBuffer();public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(5);for (int i = 0; i < 10; i++) {executor.submit(() -> {logBuffer.append("Log entry from a thread\n");});}executor.shutdown();while (!executor.isTerminated()) {// Wait for all threads to finish}System.out.println(logBuffer.toString());}}

在这个例子中,多个线程通过executor.submit方法提交任务,每个任务都向StringBuffer对象logBuffer中添加一条日志记录。由于StringBuffer是线程安全的,所以可以正确地记录所有线程的日志内容。
3. 使用 StringBuilder 的情况

  • 单线程环境下的字符串修改操作:在单线程环境中,当需要频繁地修改字符串,如进行大量的字符串拼接、插入或删除操作时,使用StringBuilder可以获得更好的性能。例如,构建一个包含大量元素的 HTML 字符串:
     public class StringBuilderUsage {public static void main(String[] args) {StringBuilder htmlBuilder = new StringBuilder();htmlBuilder.append("<html><body>");for (int i = 0; i < 100; i++) {htmlBuilder.append("<p>Paragraph " + i + "</p>");}htmlBuilder.append("</body></html>");System.out.println(htmlBuilder.toString());}}

在这个例子中,在单线程环境下使用StringBuilder来构建一个包含 100 个段落的 HTML 页面内容。由于没有多线程安全的开销,StringBuilder可以高效地完成字符串的拼接操作。

三、String#equals()和Object#equals()有何区别?

String 中的 equals 方法是被重写过的,比较的是 String 字符串的值是否相等。 Object 的 equals 方法是比较的对象的内存地址。

四、String#intern 方法有什么作用?

String.intern() 是一个 native (本地) 方法,用来处理字符串常量池中的字符串对象引用。它的工作流程可以概括为以下两种情况:

  1. 常量池中已有相同内容的字符串对象:如果字符串常量池中已经有一个与调用 intern() 方法的字符串内容相同的 String 对象,intern() 方法会直接返回常量池中该对象的引用。
  2. 常量池中没有相同内容的字符串对象:如果字符串常量池中还没有一个与调用 intern() 方法的字符串内容相同的对象,intern() 方法会将当前字符串对象的引用添加到字符串常量池中,并返回该引用。

总结:

  • intern() 方法的主要作用是确保字符串引用在常量池中的唯一性。
  • 当调用 intern() 时,如果常量池中已经存在相同内容的字符串,则返回常量池中已有对象的引用;否则,将该字符串添加到常量池并返回其引用。

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

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

相关文章

【C#】调用本机AI大模型流式返回

【python】AI Navigator的使用及搭建本机大模型_anaconda ai navigator-CSDN博客 【Python】AI Navigator对话流式输出_python ai流式返回-CSDN博客 前两章节我们讲解了使用AI Navigator软件搭建本机大模型&#xff0c;并使用python对大模型api进行调用&#xff0c;使其流式返…

JS面试八股文(一)

&#x1f60a;JS面试八股文&#xff08;一&#xff09; 1.JS由哪三部分组成&#xff1f;2.JS有哪些内置对象&#xff1f;3.操作数组的方法有哪些&#xff1f;4.JS对数据类型的检测方式有哪些&#xff1f;5.说一下闭包&#xff0c;闭包有什么特点&#xff1f;6.前端的内存泄漏怎…

【go】仅设想,能不能通过pure go编写页面。

设想 通过pure-go编写页面, 似乎不太好实现&#xff0c; 就当学习前端html基础了。 完成度 0.5% App.go: package srcimport (d "github.com/go-webtools/wgo/core/document""github.com/go-webtools/wgo/core/react""github.com/go-webtools/wgo/c…

Java避坑案例 - 高并发场景下的分布式缓存策略

文章目录 概述缓存常见问题及解决方案把 Redis 当作数据库常用的数据淘汰策略如何选择合适的驱逐算法 缓存雪崩问题复现解决方案 缓存击穿&#xff08;热点缓存失效&#xff09;问题复现解决方案 缓存穿透问题复现解决方案缓存穿透 vs 缓存击穿 缓存与数据库的一致性先更新缓存…

面包种类图像分割系统:多层面改进

面包种类图像分割系统源码&#xff06;数据集分享 [yolov8-seg-GhostHGNetV2&#xff06;yolov8-seg-C2f-DCNV3等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI Globa…

使用Llama Index与Streamlit实现一个从文本中提取专业术语和定义网页小程序

Llama Index有许多用例&#xff08;语义搜索、摘要等&#xff09;&#xff0c;并且都有很好的记录。然而&#xff0c;这并不意味着我们不能将Llama Index应用到非常具体的用例中&#xff01; 在本教程中&#xff0c;我们将介绍使用Llama Index从文本中提取专业术语和定义的设计…

Ovis: 多模态大语言模型的结构化嵌入对齐

论文题目&#xff1a;Ovis: Structural Embedding Alignment for Multimodal Large Language Model 论文地址&#xff1a;https://arxiv.org/pdf/2405.20797 github地址&#xff1a;https://github.com/AIDC-AI/Ovis/?tabreadme-ov-file 今天&#xff0c;我将分享一项重要的研…

量子机器学习:颠覆性的前沿技术

量子机器学习&#xff1a;颠覆性的前沿技术 引言 在科技日新月异的今天&#xff0c;量子计算和机器学习作为两大前沿领域&#xff0c;各自在推动科技进步中发挥着重要作用。而当这两者结合时&#xff0c;便诞生了一个全新的领域——量子机器学习&#xff08;Quantum Machine …

GCC 简介

Linux 中的编译器 GCC 的编译原理和使用详解 GCC 简介 GCC&#xff08;GNU Compiler Collection&#xff09;是一套由 GNU 开发的编程语言编译器&#xff0c;它支持多种编程语言&#xff0c;包括 C、C、Objective-C、Fortran、Ada 和 Go 等。GCC 是一个开源的工具集&#xff…

Spring Boot框架在学生宿舍管理中的应用研究

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了学生宿舍信息管理系统的开发全过程。通过分析学生宿舍信息管理系统管理的不足&#xff0c;创建了一个计算机管理学生宿舍信息管理系统的方案。文章介绍了学生宿舍…

AI读教链《为什么今年ETH对BTC表现这么拉垮?》

以太坊&#xff08;ETH&#xff09;近期表现不佳&#xff0c;主要是由于市场对其价值存储功能的信心下降&#xff0c;尤其是在比特币&#xff08;BTC&#xff09;表现强劲的背景下。ETH的市值逐渐被以Solana等新兴公链抢占&#xff0c;流失了大量用户和炒币的流量。此外&#x…

JAVA排序

排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&#xff0c;若经过排序&…

跟着鸟儿学飞行?扑翼机器人的感知秘籍

大家好&#xff01;今天来了解一篇扑翼机器人的研究——《Avian-inspired embodied perception in biohybrid flapping-wing robotics》发表于《Nature Communications》。在广阔天空中&#xff0c;鸟类凭借精妙翅膀结构与敏锐感知自由翱翔&#xff0c;这一直吸引着科学家探索其…

cherry pick commit

cherry pick commit git cherry-pick 是一个 Git 命令&#xff0c;用于将特定的提交&#xff08;commit&#xff09;应用到当前分支上。这在需要从其他分支中挑选某些提交到当前分支时非常有用&#xff0c;例如当你需要修复一个 bug&#xff0c;但想只应用特定的变更&#xff…

国内大语言模型哪家更好用?

大家好&#xff0c;我是袁庭新。 过去一年&#xff0c;AI大语言模型在爆发式增长&#xff0c;呈现百家争鸣之态。国内外相关厂商积极布局&#xff0c;并相继推出自家研发的智能化产品。 我在工作中已习惯借助AI来辅助完成些编码、创作、文生图等任务&#xff0c;甚至对它们产…

基于物联网的智慧考场系统设计(论文+源码)

1. 功能设计 &#xff08;1&#xff09;温度监测与控制功能&#xff1a; 系统需要能够实时采集考场内的温度信息&#xff0c;通过DS18B20传感器获取准确的数据&#xff0c;并在OLED屏幕和APP上显示。当温度异常过高时&#xff0c;系统应自动启动继电器&#xff0c;模拟空调开启…

【Python】深入理解Python的列表推导式与生成器表达式:简洁与性能的权衡

引言 Python因其简洁易懂的语法和强大的标准库&#xff0c;深受开发者的喜爱。为了提升代码的简洁性与可读性&#xff0c;Python引入了许多方便的语法特性&#xff0c;其中列表推导式和生成器表达式是非常重要的工具。这两者为我们提供了优雅的方式来生成序列数据&#xff0c;…

API接口开放与安全管控 - 原理与实践

API安全是接口开放的前提条件 在API对外开放时&#xff0c;确保其安全性至关重要&#xff0c;因为API直接暴露给外部环境&#xff0c;容易成为攻击目标。一旦被恶意利用&#xff0c;可能导致数据泄露、服务滥用等严重后果。因此&#xff0c;通过API网关实施严格的接口安全管理…

用“堆”模拟实现“优先级队列”

PriorityQueue优先级队列 1. 优先级队列的概念2. 优先队列的模拟实现3 堆的概念4. 堆的存储方式5. 堆向下调整6. 堆的创建7. 堆的插入8. 堆的删除9. 用堆模拟实现优先级队列 1. 优先级队列的概念 前面我们学习了队列&#xff0c;队列是一种“先进先出”的数据结构&#xff0c;…

智慧农业大数据平台:智汇田园,数驭未来

智慧农业大数据平台 计讯物联智慧农业大数据平台是一个集管理数字化、作业自动化、生产智能化、产品绿色化、环境信息化、服务现代化于一体的多功能监管系统。它通过与硬件产品的搭配使用&#xff0c;实现对农业生产全过程的实时监测、精准控制和科学管理。该平台集成了多个数…