当前位置: 首页 > news >正文

java的substring()方法在JDK 6和JDK 7中的运作机制

为什么80%的码农都做不了架构师?>>>   hot3.png

substring(int beginIndex, int endIndex) 方法在 JDK 6 和 JDK 7 中是不一样的. 了解他们之间的异同可以让你更好地使用这个方法. 为了方便表达,下文中使用 followingsubstring() 代替 substring(int beginIndex, int endIndex) 。

1. substring() 都做了什么操作?

substring(int beginIndex, int endIndex) 返回一个 beginIndex 开始到endIndex-1结束字符串 。

String x = "abcdef"; x = x.substring(1,3); System.out.println(x);

Output:

bc


2. 当 substring() 被调用的时候会发生什么?

因为字符串x是不可变的, 当x.substring(1,3)方法返回的字符串赋值给x, 它会像下图那样指向一个全新的字符串:

string-immutability

但是上面的图并不是完全的正确描述了substring()方法被调用的时候内存发生了什么变化,它仅仅描述了 堆内存中发生了什么. 

3. substring() in JDK 6

字符串内部是用字符数组来实现的. 在 JDK 6 中, String 包含了3个字段: char value[], int offset, int count. 用它们来存储一个字符数组, 数组在内存中的第一个索引, 字符串包含字符的数量.

当 substring() 方法被调用的时候, 它会创建一个新的字符串, 但字符串的值仍然指向堆内存中原来的字符串值. 这两个字符串的不同在于它们的offset count.

string-substring-jdk6

下面的代码简单的演示了发生了什么操作


//JDK 6 
String(int offset, int count, char value[]) {
 this.value = value;
 this.offset = offset;
 this.count = count; 

}   

public String substring(int beginIndex, int endIndex) { 
//check boundary 
return new String(offset + beginIndex, endIndex - beginIndex, value); 
}




4. 在 JDK 6中调用substring()可能会导致一个性能问题

如果你有一个非常长的字符串, 但你每次调用 substring()的时候只截取其中很小的一部分. 因为你只需要很小的一部分,但是在内存中存储了一个很长的数组,这样会导致程序性能不好. 在 JDK 6 中, 我们将会使用下面的方法来解决这个问题, 它会指向一个新的sub string:

x = x.substring(x, y) + ""

5. substring() in JDK 7

这个方法在JDK 7中有了提升,每一次调用substring()都会在堆内存中创建一个新的字符串数组

string-substring-jdk7


//JDK 7 
public String(char value[], int offset, int count) { 
//check boundary 
this.value = Arrays.copyOfRange(value, offset, offset + count);
 }  
 public String substring(int beginIndex, int endIndex) { 
//check boundary
 int subLen = endIndex - beginIndex;
 return new String(value, beginIndex, subLen); 
}


/**************************我是分隔线******************************/

下面的网友评论中有人提出x = x.substring(x, y) + ""这个方法不好,因为它等同于

StringBuilder sb = new StringBuilder();
sb.append(x.substring(x, y));
sb.append("");
x = sb.toString();



可以用下面的方法来代替x = x.substring(x, y) + ""

x = new String(x.substring(x, y));


转载于:https://my.oschina.net/u/865092/blog/180278

相关文章:

  • 【译】在Asp.Net中操作PDF - iTextSharp - 利用列进行排版
  • MYSQL—自动备份脚本(网友版)
  • 有关T-SQL的10个好习惯
  • 初识Postgresql和Sqoop
  • jquery validationEngine的使用
  • sqlserver排序规则在全角与半角处理中的应用
  • WSGI 简单服务器请求
  • Command line option syntax error. Type Command /? for Help.
  • 项目管理学习之(2)-避免打地鼠式开发
  • @angular/cli项目构建--Dynamic.Form
  • 解决getOutputStream() has already been called for this response
  • spring boot下thymeleaf全局静态变量配置
  • ajax提交数据处理总结
  • django.http.response中HttpResponse 子类
  • SpringMVC三种异常处理方式
  • 【Leetcode】101. 对称二叉树
  • DataBase in Android
  • extract-text-webpack-plugin用法
  • Java 内存分配及垃圾回收机制初探
  • Javascripit类型转换比较那点事儿,双等号(==)
  • Linux下的乱码问题
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • Spring Cloud中负载均衡器概览
  • vuex 学习笔记 01
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 蓝海存储开关机注意事项总结
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • (01)ORB-SLAM2源码无死角解析-(56) 闭环线程→计算Sim3:理论推导(1)求解s,t
  • (12)目标检测_SSD基于pytorch搭建代码
  • (4) PIVOT 和 UPIVOT 的使用
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (二)正点原子I.MX6ULL u-boot移植
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (四)Android布局类型(线性布局LinearLayout)
  • (四)Controller接口控制器详解(三)
  • (四)模仿学习-完成后台管理页面查询
  • (未解决)macOS matplotlib 中文是方框
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)
  • (转)es进行聚合操作时提示Fielddata is disabled on text fields by default
  • (转)菜鸟学数据库(三)——存储过程
  • (转)原始图像数据和PDF中的图像数据
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • .bat批处理(七):PC端从手机内复制文件到本地
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑
  • .NET Framework杂记
  • .NET Standard、.NET Framework 、.NET Core三者的关系与区别?
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
  • .net的socket示例
  • .net访问oracle数据库性能问题
  • .net通用权限框架B/S (三)--MODEL层(2)
  • ;号自动换行
  • [\u4e00-\u9fa5] //匹配中文字符