浅谈java字符串

浅谈JAVA字符串 1)求取java字符串长度可以使用length()方法,(空格算一个长度) 返回结果 2)连接字符串可以使用“+”进行操作 返回结果 3)字符串截取 substring(beginIndex) 从特定位置字符串到字符串结尾 注意下标从0开始 范围结果为 substring(beginIndex,endIndex) 当函数参数为两个时,第一个为当前选中的位置,第二个为endIndex-1;注意第二个参数是选中位置前一个参数 结果为 如果... 阅读详情

java字符串相关的类有三个,String、StringBuilder、StringBuffer,下面浅谈一下三者的区别

String

我们先看源码中它的属性(也就是用什么保存数据)

    /** The value is used for character storage. */
    private final char value[];

    /** Cache the hash code for the string */
    private int hash; // Default to 0

这是最重要的两个属性,我们重点看一下value,它是一个字符串数组,用来保存string的内容,值得注意的是,它是final的,也就意味值一旦赋值,就不可改变。所以大家经常说的string类型是不可变的就是这个意思,但是如果不能变的话,它怎样执行toLowerCase()和replace等操作呢?它是通过创建新的字符数组,然后作为返回值来实现的。我们可以看下下面的代码就知道了。

        public String replace(char oldChar, char newChar) {
        if (oldChar != newChar) {
            int len = value.length;
            int i = -1;
            char[] val = value; /* avoid getfield opcode */

            while (++i < len) {
                if (val[i] == oldChar) {
                    break;
                }
            }
            if (i < len) {
                char buf[] = new char[len];
                for (int j = 0; j < i; j++) {
                    buf[j] = val[j];
                }
                while (i < len) {
                    char c = val[i];
                    buf[i] = (c == oldChar) ? newChar : c;
                    i++;
                }
                return new String(buf, true);
            }
        }
        return this;
    }

因为每次执行这些操作都要重新创建新的字符串,所以String的效率就会受影响。

但是java设计者这样设计肯定是有他的原因的,主要原因是一下三个方面:

1.字符串池的需求

java中string对象有一个大家都知道的创建方法:

      String str = "abc";

通过这种方法创建的字符串对象保存在字符串池中,(字符串池既不在栈中,也不在堆中,而是保存在独特的方法区中),创建的时候,先在字符串池中寻找是否存在“abc”,如果存在,则直接把它的引用赋值给str,如果不存在,则创建后赋值。这里需要注意的是,字符串池中的字符串并不会因为失去引用而被垃圾回收机制回收。

如果字符串不是不可改变的,那么一个引用字符串的改变,将会导致另外一个引用出现脏数据。

2.允许字符串缓存哈希码

在java中经常会用到字符串的哈希码(可以看前面String中hash的定义),String的不变性保证了哈希码的始终如一,所以也就不用担心哈希码发生变化,这样的话,就不用在使用的时候每次都计算重新计算哈希码,效果就会高很多。

3.安全

String广泛的用于java 类中的参数,如:网络连接(Network connetion),打开文件(opening files )等等。如果String不是不可变的,网络连接、文件将会被改变——这将会导致一系列的安全威胁。操作的方法本以为连接上了一台机器,但实际上却不是。由于反射中的参数都是字符串,同样,也会引起一系列的安全问题。下面给一个代码例子:

   boolean connect(string s){
    if (!isSecure(s)) { 
      throw new SecurityException(); 
    }
    //here will cause problem, if s is changed before this by using other references.    
    causeProblem(s);
    } 

StringBuilder

public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence

从上面定义可以看到,StringBuild是从AbstractStringBuilder继承而来,大家有兴趣的话可以去看一下它们的源代码。

StringBuilder与string不同的地方在于,他是初始使用长度为16的char[]来存储数据,如果字符串长度超过则自动扩展,所以他能够实现在原来字符串上添加字符而不需要重新创建一个新的字符串。

可以使用toString方法将它转换成string

StringBuffer

StringBuffer也是从AbstractStringBuilder继承而来,它与stringbuffer的区别在于:

  • StringBuileder是一个单线程使用的类,不执行线程同步,所以StringBuilder速度比较快,效率比较高,但是是线程不安全的。
  • StringBuffer是线程安全的,所以相对应的,就要牺牲一下速度和效率。

三者执行效率比较

一般来说,三者的执行效率为 StringBuilder > StringBuffer > String

一道经典的面试题

以下代码创建了多少个对象

    String str = new String("a" + "b");

一般来说,我们可以这样理解:首先创建对象”a“和”b“,然后创建“ab”,这三个都是存在于字符串池中,最后再用“ab“当参数,在堆中new一个字符串,所以总共创建了4个对象。注意:str不是对象,只是对象的引用。

但是实际上并没有创建4个对象,只创建了两个对象,因为编译器进行了自动优化:编译器创建了一个StringBuilder对象,并为”a“和”b“分别调用一次append()方法,最后调用toString()方法时候生成结果。所以现在为止只生成了一个对象。然后new让他在堆上创建一个对象,所以,是两个对象。

那么大家就会这样想,既然编译器会自动进行优化,那我们就放心用string就好了,其实也不尽然,因为编译器优化还是有限的,我们来看下面的例子(thinking in java 中的例子):

//: strings/WhitherStringBuilder.java
    //使用string
    public class WhitherStringBuilder {
      public String implicit(String[] fields) {
        String result = "";
        for(int i = 0; i < fields.length; i++)
          result += fields[i];
        return result;
      }

      //使用stringBuffer
    public String explicit(String[] fields) {
        StringBuilder result = new StringBuilder();
        for(int i = 0; i < fields.length; i++)
          result.append(fields[i]);
        return result.toString();
      }
    } 

使用string的话,在for循环中,每一次都会创建一个StringBuilder对象,但是一开始就使用StringBuilder的话,全程只会有一个StringBuilder对象。关于这一点的验证,要涉及到汇编语言,在这里就不展开讨论了。所以,我们可以看到,编译器的优化能力还是有限的。

浅谈 Java 中字符串的初始化(详细图解) 前言 在深入学习字符串类之前,我们先搞懂JVM是怎样处理新生字符串的。当你知道字符串的初始化细节后,再去写String s = "hello"或String s = new String("hello")等代码时,就能做到心中有数。 首先得搞懂字符串常量池的概念,下面进入正文吧。 常量池 把经常用到的数据存放在某块内存中,避免频繁的数据创建与销毁,实现数据共享,提高系统性能。 八种基础数据类型除了float和double都实现了常量池技术。在近代的JDK版本中(1.7后),字符串常量池被实现在 阅读详情

相关推荐

XC7K325T FPGA硬件设计实战:从板级原理图到高速接口优化

本文以XC7K325T FPGA为核心,详细阐述了从板级原理图设计到高速接口优化的完整硬件实战流程。内容涵盖芯片管脚与电源规划、时钟复位配置电路设计,并重点解析了DDR3内存子系统以及PCIe与光纤接口等高速电路的原理图与PCB设计要点,旨在帮助工程师构建稳定可靠的高性能硬件平台。

python9snake的博客 512

浅谈Java字符串

常用操作字符串遍历类型转换取子字符串分割字符串可变字符串 Java的字符串由String类来构造,一个String值是一串可以由索引访问的char值。 字符串遍历 String str = "acdfjkl"; 直接利用索引 for (int i = 0; i &lt; str.length(); i++){ char ch = str.charAt(i); } 转化为字符数...

单向代码馆 199

RK3568/RK3588之修改8250驱动实现RS485收发的自动切换

在串口发送前,若为485,则将控制引脚拉为发送状态,在发送后,循环查看是否发送完成,若发送完成则将引脚置回读状态,如此一来,就能实现在内核测控制方向切换,而不会因为延时造成数据丢失,经过测试此办法可行。全部修改完成后,重新编译生成内核文件和设备树文件,烧写到板子上即可。

哒宰的博客 3113

浅谈Java中字符串的初始化及字符串操作类

大家好,我是本周的值班编辑 江南一点雨 ,本周将由我为大家排版并送出技术干货,大家可以在公众号后台回复“springboot”,获取最新版 Spring Boot2.1....

Java极客技术 5602

数字取证双雄:Passware Kit Forensic 与 ElcomSoft 在实战场景下的能力边界解析

本文深入解析了Passware Kit Forensic与ElcomSoft在数字取证实战中的能力边界,涵盖Windows、macOS、iOS和Android系统的密码恢复与数据提取技术。通过真实案例对比两款工具在硬件加速、分布式计算及云取证等场景下的表现差异,为取证专家提供关键决策参考。特别探讨了密码恢复软件在加密设备突破中的核心作用。

weixin_30342209的博客 398

Deepfake检测模型-PyDeepFakeDet项目复现实验报告-深度学习

该实验是对于https://github.com/wangjk666/PyDeepFakeDet模型的复现。PyDeepFakeDet 是一款集成的、可扩展的 Deepfake 检测工具。目标是提供最先进的 Deepfake 检测模型以及用于在常用 Deepfake 数据集上训练和评估新模型的接口。

一位不是很硕的鉴伪方向硕士 5494

浅谈java中几种字符串拼接

当我们需要对字符串进行拼接时,我们首先想到的是最简单直观的String中的+=,但是,这种方式是不是最优的呢,如果是在次数很多的循环中呢?于是探究了java中字符串拼接的四种方法,比较了一下他们的利弊关系。 [b]下面是测试的代码:[/b][code="java"][/code] public class StringJoint { private int count = 50000...

lizhiyu323的博客 490

Python 爬虫教程:抓取视频平台数据(观看量、评论数、点赞数等)

爬虫(Crawler)是通过编写程序模拟浏览器行为,从互联网上抓取并提取信息的技术。爬虫的核心任务是模拟用户访问网页,获取网页内容并解析出我们需要的数据。爬虫技术被广泛应用于搜索引擎、数据分析、电商价格监控、内容抓取等领域。Bilibili和YouTube。这两个平台都提供丰富的用户生成内容(UGC),且在中国和全球范围内都非常流行。Bilibili:以二次元文化为主的视频平台,用户活跃,视频内容丰富。Bilibili的网页数据较为简单,可以通过传统的HTML解析抓取。YouTube。

2201_76125261的博客 1854

浅谈 Java 字符串

文章转载自:http://github.thinkingbar.com/how-to-use-string/ 我们先要记住三者的特征: String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全) 一、定义 查看API会发现,String、StringBuffer、StringBuilder都实现了

布道之道 638

在SAP系统中创建物料 860000000000000082(物料描述为“8680月球广寒宫坦克车”)时,系统报出了一个错误

摘要:SAP系统创建物料"8680月球广寒宫坦克车"时出现"C+020"错误,提示评估区域C916未在物料分类账中设置为生产性。解决方案需进入"会计-控制-产品成本控制-实际成本核算"路径,将评估区域C916手动设置为生产性状态。该操作需由具备权限的系统管理员或FICO顾问执行,建议操作前进行数据备份或在测试环境验证。完成设置后即可重新创建物料。

金牌架构师 391

功能安全实战系列12-英飞凌TC3xx锁步核及其自检开发

本文介绍了英飞凌Tricore系列芯片的锁步核(Lockstep Core)功能及其故障注入自检机制。锁步核通过主核和检查核同步执行指令,并比较输出结果来检测硬件故障。文章详细阐述了锁步核的工作原理、使能配置方法以及故障注入自检的实现过程。故障注入测试通过专用寄存器LCLTEST触发,系统会定期自动测试比较器节点,验证锁步核的故障检测能力。当检测到异常时,会触发SMU模块的警报机制。该技术为汽车电子系统提供了重要的功能安全保障。

initiallizer的博客 919

浅谈一下java中字符串拼接方法

这些方法各有优缺点,通常在需要频繁拼接时,推荐使用 StringBuilder,因为它性能更好。对于简单的拼接,使用 + 运算符或 String.join() 方法都是不错的选择。当需要拼接多个字符串时,使用 StringBuilder(或 StringBuffer,它是线程安全的)更高效,因为它们是可变的。String.join() 方法可以方便地将多个字符串连接起来,使用指定的分隔符。String.format() 允许使用格式化字符串进行拼接。这是最简单直接的方法,可以直接使用 + 来拼接字符串。

cheng_ji的专栏 1198

最佳RANSAC算法拟合矩形的实现(基于PCL库)

最佳RANSAC算法是一种常用的参数估计方法,用于从数据集中拟合出最佳的模型。在计算机视觉和图像处理领域,最佳RANSAC算法常用于拟合几何形状,如矩形。本文将详细介绍如何使用点云库(PCL)中的最佳RANSAC算法来拟合矩形,并提供相应的源代码。

JbPatch的博客 1541

java uncked_浅谈Java字符串

从概念上而言,Java字符串就是Unicode字符序列。由于Java没有内置的字符串类型,而是在标准Java类库中提供了一个预定义类String,每个用双引号的括起来的字符串都是String类的一个实例:String t = ""; //空字符串String t = "Hello"; //字符串t的内容为Hello很自然地,我们会考虑对字符串进行操作,比如取字符串中的子串进行操作,这里我们就要用到...

weixin_39760065的博客 119

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

浅谈我对JAVA字符串的了解

在JAVA程序里边,我们操作最多的,也就是字符串了,字符串可谓是最常见的类了, 现在我来说说String类的应用范畴 , 打开API文档,在java.lang包下有个String类,下面我来说说该类下常见的字符串操作 ,

XoPtimal 394

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

浅谈 java 字符串

1、Thinking in Java中详细介绍了当程序运行的时候,具体的内存分配。 可以分为寄存器、堆栈、堆、常量存储、非RAM存储。 2、Java中的数据类型有两种。 一种是基本类型(primitive types), 共有8种,即int, short, long, byte, float, double, boolean, char(注意,并没有string的基本类型)。 这

zt928815211的专栏 433

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

浅谈Java语法中的字符串:String

浅谈Java语法中的字符串:String

weixin_64308540的博客 1439

JAVA 十六进制与字符串的转换浅谈

笔者前几日在开服过程中需要将字符串转化成为16进制的字符串,在网上找到了一些方法尝试之后,均发现存在一个问题-->字符串转为16进制后再转回来,英文正常,中文出现乱码。笔者前几日在开服过程中需要将字符串转化成为16进制的字符串,在网上找到了一些方法尝试之后,均发现存在一个问题-->字符串转为16进制后再转回来,英文正常,中文出现乱码。1)在将字符串转为16进制之前先进行一次转化,先将其转化成为Unicode编码(相当于把中文用英文字符代替),在转化成为16进制。*字符串转为16进制。*16进制转为字符串。

hdxx2022的博客 6049

java字符串要前三个_浅谈 Java 字符串

我们先要记住三者的特征:String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全)一、定义查看API会发现,String、StringBuffer、StringBuilder都实现了 CharSequence接口,虽然它们都与字符串相关,但是其处理机制不同。String:是不可改变的量,也就是创建后就不能在修改了。StringBuf...

weixin_39856265的博客 169

浅谈java中string字符串比较。

当我们使用“==”进行比较时;引用数据类型比较的是地址值。new出来地对象会开辟在堆中;所以他们地址不相等。

Fanyuefriend的博客 603

浅谈JAVA中字符串常量的储存位置

在讲述这些之前我们需要一些预备知识: Java的内存结构我们可以通过两个方面去看待它。 一、从抽象的JVM的角度去看。相关定义请参考JVM规范:Chapter 2. The Structure of the Java Virtual Machine 从该角度看的话Java内存结构包含以下部分:该部分内容可以结合:JVM简介(更加详细深入的介绍) 1、栈区:由编译器自动分配释放,具...

anaijiao0225的博客 179
下一篇: Java数组拷贝的四种方法
Abyjun
博客等级 码龄15年 10粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值