字符串String中的拼接细节及intern方法 记录一

2024-02-22 21:48

本文主要是介绍字符串String中的拼接细节及intern方法 记录一,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

问题1: String s = "a" + "b" + "c" + "d" + "e";
 问此语句共创建了几个对象,

 答案是
 就创建了一个
 String s = "a" + "b" + "c" + "d" + "e";
 赋值符号右边的"a"、"b"、"c"、"d"、"e"都是常量
 对于常量,编译时就直接存储它们的字面值而不是它们的引用
 在编译时就直接讲它们连接的结果提取出来变成了"abcde"
 该语句在class文件中就相当于String s = "abcde"
 然后当JVM执行到这一句的时候, 就在String pool里找
 如果没有这个字符串,就会产生一个


问题2:但是如果改成 String s = a+b+c+d+e;
 呢 又是几个了。

 就是说上面是一个是因为 "a"、"b"、"c"、"d"、"e"都是常量
 但如果是变量呢?



我的答案是3个对象,但只有一个String对象:

由于编译器的优化,最终代码为通过StringBuilder完成:
StringBuilder builder = new StringBuilder();
builder.append(a);
builder.append(b);
builder.append(c);
builder.append(d);
builder.append(e);
String s = builder.toString();


我们先看看StringBuilder的构造器
    public StringBuilder() {
      super(16);
    }
看下去
    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }
可见,分配了一个16自己长度的char数组

我们看看append的整个过程(注意,源代码我从各个类进行了整合,他们实际上不在一个类里面的)

  public StringBuilder append(String str) {
    super.append(str);
    return this;
  }

  public AbstractStringBuilder append(String str) {
    if (str == null)
      str = "null";
    int len = str.length();
    if (len == 0)
      return this;
    int newCount = count + len;
    if (newCount > value.length)
      expandCapacity(newCount);
    str.getChars(0, len, value, count);
    count = newCount;
    return this;
  }

  public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
    if (srcBegin < 0) {
      throw new StringIndexOutOfBoundsException(srcBegin);
    }
    if (srcEnd > count) {
      throw new StringIndexOutOfBoundsException(srcEnd);
    }
    if (srcBegin > srcEnd) {
      throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
    }
    System
        .arraycopy(value, offset + srcBegin, dst, dstBegin, srcEnd - srcBegin);
  }
可见,我们的代码不会超过16个,所以不会出现扩展value的情况。
而append里面使用了arraycopy的复制方式,也没有产生新的对象。

最后,我们再看StringBuilder的 toString()方法:  public String toString() {
    // Create a copy, don't share the array
    return new String(value, 0, count);
  }
这里通过前面的数组生成了一个新的String。



大家注意那个默认的16容量,如果题目出现了总长度超过16,则会出现如下的再次分配的情况
  void expandCapacity(int minimumCapacity) {
    int newCapacity = (value.length + 1) * 2;
    if (newCapacity < 0) {
      newCapacity = Integer.MAX_VALUE;
    } else if (minimumCapacity > newCapacity) {
      newCapacity = minimumCapacity;
    }
    value = Arrays.copyOf(value, newCapacity);
  }

  public static char[] copyOf(char[] original, int newLength) {
    char[] copy = new char[newLength];
    System
        .arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
    return copy;
  }
可见,expand容量时,增加为当前(长度+1)*2。
注意这里用了Arrays的方法,注意不是前面的 System.arraycopy方法哦。这里产生了一个新的
copy的char数组,长度为新的长度


总结:三个对象分别为
1 StringBuilder
2 new char[capacity]
3 new String(value,0,count);

如果说String对象,则为1个。



这篇关于字符串String中的拼接细节及intern方法 记录一的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/736597

相关文章

Python安装Pandas库的两种方法

《Python安装Pandas库的两种方法》本文介绍了三种安装PythonPandas库的方法,通过cmd命令行安装并解决版本冲突,手动下载whl文件安装,更换国内镜像源加速下载,最后建议用pipli... 目录方法一:cmd命令行执行pip install pandas方法二:找到pandas下载库,然后

MySQL常用字符串函数示例和场景介绍

《MySQL常用字符串函数示例和场景介绍》MySQL提供了丰富的字符串函数帮助我们高效地对字符串进行处理、转换和分析,本文我将全面且深入地介绍MySQL常用的字符串函数,并结合具体示例和场景,帮你熟练... 目录一、字符串函数概述1.1 字符串函数的作用1.2 字符串函数分类二、字符串长度与统计函数2.1

java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)

《java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)》:本文主要介绍java中pdf模版填充表单踩坑的相关资料,OpenPDF、iText、PDFBox是三... 目录准备Pdf模版方法1:itextpdf7填充表单(1)加入依赖(2)代码(3)遇到的问题方法2:pd

C# $字符串插值的使用

《C#$字符串插值的使用》本文介绍了C#中的字符串插值功能,详细介绍了使用$符号的实现方式,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录$ 字符使用方式创建内插字符串包含不同的数据类型控制内插表达式的格式控制内插表达式的对齐方式内插表达式中使用转义序列内插表达式中使用

Linux系统中查询JDK安装目录的几种常用方法

《Linux系统中查询JDK安装目录的几种常用方法》:本文主要介绍Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目... 目录方法 1:通过update-alternatives查询(推荐)方法 2:检查所有已安装的 JDK方

SQL Server安装时候没有中文选项的解决方法

《SQLServer安装时候没有中文选项的解决方法》用户安装SQLServer时界面全英文,无中文选项,通过修改安装设置中的国家或地区为中文中国,重启安装程序后界面恢复中文,解决了问题,对SQLSe... 你是不是在安装SQL Server时候发现安装界面和别人不同,并且无论如何都没有中文选项?这个问题也

Java Thread中join方法使用举例详解

《JavaThread中join方法使用举例详解》JavaThread中join()方法主要是让调用改方法的thread完成run方法里面的东西后,在执行join()方法后面的代码,这篇文章主要介绍... 目录前言1.join()方法的定义和作用2.join()方法的三个重载版本3.join()方法的工作原

Java获取当前时间String类型和Date类型方式

《Java获取当前时间String类型和Date类型方式》:本文主要介绍Java获取当前时间String类型和Date类型方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录Java获取当前时间String和Date类型String类型和Date类型输出结果总结Java获取

详解MySQL中JSON数据类型用法及与传统JSON字符串对比

《详解MySQL中JSON数据类型用法及与传统JSON字符串对比》MySQL从5.7版本开始引入了JSON数据类型,专门用于存储JSON格式的数据,本文将为大家简单介绍一下MySQL中JSON数据类型... 目录前言基本用法jsON数据类型 vs 传统JSON字符串1. 存储方式2. 查询方式对比3. 索引

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分