上一节主要介绍了String类的一些构造方法,主要分为四类

  • 无参构造器:String(),创建一个空字符串"",区别于null字符串,""已经初始化,null并未初始化
  • 副本构造器:String(String s),简单的赋值,得到的是一个副本,俩个引用指向的是常量池中的同一个String,但是String是不可变的,所有用意不大
  • byte类构造器:String(byte[] b),将byte数组转换为String,注意并不是简单的赋值,而是整体copy一份
  • char类构造器:String(char[] c),将char数组转换成String,注意并不是简单的赋值,而是整体copy一份
  • codepoints构构器:String(int[] i),将超过char表示范围的字符转换为为String
  • String缓存流的转换:String(StringBuffer),将字符换缓冲流转换为String
  1. /*
  2. * 获得字符串的长度,也就是属性value数组的长度
  3. */
  4. public int length() {
  5. return value.length;
  6. }
  7.  
  8. /*
  9. * 判断字符串是否为空,也就是判断属性value数组的长度是否等于0
  10. */
  11. public boolean isEmpty() {
  12. return value.length == 0;
  13. }
  14.  
  15. /*
  16. * charAt方法可以直接获取当前下标对应的字符,这对于判断某个位置的字符值很方便
  17. * 区别于
  18. */
  19. public char charAt(int index) {
  20. if ((index < 0) || (index >= value.length)) {
  21. throw new StringIndexOutOfBoundsException(index);
  22. }
  23. return value[index];
  24. }
  25.  
  26. /*
  27. * 返回指定索引处的字符(Unicode代码点)。 codePoint在上一章已经介绍过了,具体就是那些超出byte和char表示方位的字符
  28. */
  29. public int codePointAt(int index) {
  30. if ((index < 0) || (index >= value.length)) {
  31. throw new StringIndexOutOfBoundsException(index);
  32. }
  33. return Character.codePointAtImpl(value, index, value.length);
  34. }
  35.  
  36. /*
  37. * 返回指定索引之前的字符(Unicode代码点)。
  38. */
  39. public int codePointBefore(int index) {
  40. int i = index - 1;
  41. if ((i < 0) || (i >= value.length)) {
  42. throw new StringIndexOutOfBoundsException(index);
  43. }
  44. return Character.codePointBeforeImpl(value, index, 0);
  45. }
  46.  
  47. /*
  48. * 返回此 String指定文本范围内的Unicode代码点数。
  49. */
  50. public int codePointCount(int beginIndex, int endIndex) {
  51. if (beginIndex < 0 || endIndex > value.length || beginIndex > endIndex) {
  52. throw new IndexOutOfBoundsException();
  53. }
  54. return Character.codePointCountImpl(value, beginIndex, endIndex - beginIndex);
  55. }
  56.  
  57. /*
  58. * 返回此String中的索引,该索引通过codePointOffset代码点从给定的index偏移。
  59. * index和codePointOffset给出的文本范围内的未配对代理计为每个代码点。
  60. *
  61. */
  62. public int offsetByCodePoints(int index, int codePointOffset) {
  63. if (index < 0 || index > value.length) {
  64. throw new IndexOutOfBoundsException();
  65. }
  66. return Character.offsetByCodePointsImpl(value, 0, value.length, index, codePointOffset);
  67. }
  68.  
  69. /*
  70. * 将此字符串复制给dst字节数组,默认为整体复制,其中dstBegin为目标数组dst中的开始位置
  71. * 此方法为包访问权限,所以我们并没有调用的权限
  72. */
  73. void getChars(char dst[], int dstBegin) {
  74. System.arraycopy(value, 0, dst, dstBegin, value.length);
  75. }
  76.  
  77. /*
  78. * 将此字符串的额指定位置开始到指定位置结束复制给dst字节数组,其中dstBegin为目标数组dst的开始位置,
  79. * srcBegin和srcEnd分别为本字符串的开始位置和结束位置
  80. */
  81. public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
  82. if (srcBegin < 0) {
  83. throw new StringIndexOutOfBoundsException(srcBegin);
  84. }
  85. if (srcEnd > value.length) {
  86. throw new StringIndexOutOfBoundsException(srcEnd);
  87. }
  88. if (srcBegin > srcEnd) {
  89. throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
  90. }
  91. System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
  92. }
  93.  
  94. /*
  95. * 方法已过时
  96. * 使用平台的默认字符集将此 String编码为字节序列,将结果存储到新的字节数组中,可以指定字符串的开始位置和结束位置,
  97. * 但结果往往是不正确的,在源码中我们可以看到,仅仅是将字符串的每一位字符强转成字节类型,实际用处很少。
  98. *
  99. */
  100. @Deprecated
  101. public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) {
  102. if (srcBegin < 0) {
  103. throw new StringIndexOutOfBoundsException(srcBegin);
  104. }
  105. if (srcEnd > value.length) {
  106. throw new StringIndexOutOfBoundsException(srcEnd);
  107. }
  108. if (srcBegin > srcEnd) {
  109. throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
  110. }
  111. Objects.requireNonNull(dst);
  112.  
  113. int j = dstBegin;
  114. int n = srcEnd;
  115. int i = srcBegin;
  116. char[] val = value; /* avoid getfield opcode */
  117.  
  118. while (i < n) {
  119. dst[j++] = (byte) val[i++];
  120. }
  121. }
  122.  
  123. /*
  124. * 指定编码字符集将此 String编码为字节序列,将结果存储到新的字节数组中
  125. */
  126. public byte[] getBytes(String charsetName) throws UnsupportedEncodingException {
  127. if (charsetName == null)
  128. throw new NullPointerException();
  129. return StringCoding.encode(charsetName, value, 0, value.length);
  130. }
  131.  
  132. /*
  133. * 指定编码字符集将此 String编码为字节序列,将结果存储到新的字节数组中
  134. */
  135. public byte[] getBytes(Charset charset) {
  136. if (charset == null)
  137. throw new NullPointerException();
  138. return StringCoding.encode(charset, value, 0, value.length);
  139. }
  140.  
  141. /*
  142. * 使用平台的默认字符集将此 String编码为字节序列,将结果存储到新的字节数组中
  143. */
  144. public byte[] getBytes() {
  145. return StringCoding.encode(value, 0, value.length);
  146. }
  147.  
  148. /*
  149. * String重写Object类的equals方法,详细阅读源码,我们发现形参是Object类型,那么在实际传参的过程当中
  150. * 除了String类型,别的引用类型都会返回false,重点注意的是StringBuffer和StringBuild,在实际比较的时候一定要先进行转换
  151. * equals实际比较的就是字符串的每一位依次进行比较,直到全部比较完毕都没有不一样的才返回true
  152. */
  153. public boolean equals(Object anObject) {
  154. if (this == anObject) {
  155. return true;
  156. }
  157. if (anObject instanceof String) {
  158. String anotherString = (String) anObject;
  159. int n = value.length;
  160. if (n == anotherString.value.length) {
  161. char v1[] = value;
  162. char v2[] = anotherString.value;
  163. int i = 0;
  164. while (n-- != 0) {
  165. if (v1[i] != v2[i])
  166. return false;
  167. i++;
  168. }
  169. return true;
  170. }
  171. }
  172. return false;
  173. }
  174.  
  175. /*
  176. * 将此字符串与指定的StringBuffer进行 比较内容是否相等
  177. */
  178. public boolean contentEquals(StringBuffer sb) {
  179. return contentEquals((CharSequence) sb);
  180. }
  181.  
  182. private boolean nonSyncContentEquals(AbstractStringBuilder sb) {
  183. char v1[] = value;
  184. char v2[] = sb.getValue();
  185. int n = v1.length;
  186. if (n != sb.length()) {
  187. return false;
  188. }
  189. for (int i = 0; i < n; i++) {
  190. if (v1[i] != v2[i]) {
  191. return false;
  192. }
  193. }
  194. return true;
  195. }
  196.  
  197. /*
  198. * 将此字符串与指定的CharSequence进行内容比较是否相等
  199. */
  200. public boolean contentEquals(CharSequence cs) {
  201. // Argument is a StringBuffer, StringBuilder
  202. if (cs instanceof AbstractStringBuilder) {
  203. if (cs instanceof StringBuffer) {
  204. synchronized (cs) {
  205. return nonSyncContentEquals((AbstractStringBuilder) cs);
  206. }
  207. } else {
  208. return nonSyncContentEquals((AbstractStringBuilder) cs);
  209. }
  210. }
  211. // Argument is a String
  212. if (cs instanceof String) {
  213. return equals(cs);
  214. }
  215. // Argument is a generic CharSequence
  216. char v1[] = value;
  217. int n = v1.length;
  218. if (n != cs.length()) {
  219. return false;
  220. }
  221. for (int i = 0; i < n; i++) {
  222. if (v1[i] != cs.charAt(i)) {
  223. return false;
  224. }
  225. }
  226. return true;
  227. }
  228.  
  229. /*
  230. * 能用一行代价解决的事就不用俩行,三元运算符?:直接解决。其中regionMatches(true, 0, anotherString, 0, value.length)是测试是否相等的函数
  231. * 第一个参数true代表忽略大小写
  232. */
  233. public boolean equalsIgnoreCase(String anotherString) {
  234. return (this == anotherString) ? true
  235. : (anotherString != null) && (anotherString.value.length == value.length)
  236. && regionMatches(true, 0, anotherString, 0, value.length);
  237. }

java源码解析之String类(二)的更多相关文章

  1. java源码解析之String类(一)

    String是我们接触最多的类,无论是学习中还是工作中,基本每天都会和字符串打交道,从字符串本身的各种拼接.切片.变形,再到和其他基本数据类型的转换,几乎无时无刻都在使用它,今天就让我们揭开Strin ...

  2. java源码解析之String类(三)

    上一节我们主要讲了String类的一些不是很常用的方法,其中需要掌握的如下,我就不再赘述了 public int length() public boolean isEmpty() public by ...

  3. java源码解析之String类(四)

    /* * 返回指定字符第一次出现的字符串内的索引 */ public int indexOf(int ch) { return indexOf(ch, 0); } /* * 返回指定字符第一次出现的字 ...

  4. java源码解析之String类(五)

    /* * 切片函数,非常重要,这里一定要牢记beginIndex是开始位置,endIndex是结束位置,区别于以前学的offset是开始位置,而count或length是个数和长度 * 比如说,new ...

  5. Java源码解析——集合框架(二)——ArrayBlockingQueue

    ArrayBlockingQueue源码解析 ArrayBlockingQueue是一个阻塞式的队列,继承自AbstractBlockingQueue,间接的实现了Queue接口和Collection ...

  6. java源码解析之Object类

    一.Object类概述   Object类是java中类层次的根,是所有类的基类.在编译时会自动导入.Object中的方法如下: 二.方法详解   Object的方法可以分成两类,一类是被关键字fin ...

  7. Spring源码解析之ConfigurationClassPostProcessor(二)

    上一个章节,笔者向大家介绍了spring是如何来过滤配置类的,下面我们来看看在过滤出配置类后,spring是如何来解析配置类的.首先过滤出来的配置类会存放在configCandidates列表, 在代 ...

  8. [Java源码解析] -- String类的compareTo(String otherString)方法的源码解析

    String类下的compareTo(String otherString)方法的源码解析 一. 前言 近日研究了一下String类的一些方法, 通过查看源码, 对一些常用的方法也有了更透彻的认识,  ...

  9. [java源码解析]对HashMap源码的分析(二)

    上文我们讲了HashMap那骚骚的逻辑结构,这一篇我们来吹吹它的实现思想,也就是算法层面.有兴趣看下或者回顾上一篇HashMap逻辑层面的,可以看下HashMap源码解析(一).使用了哈希表得“拉链法 ...

随机推荐

  1. 史上最全最强SpringMVC详细示例实战教程【good】

    1)Spring MVC 在调用处理方法之前,在请求线程中自动的创建一个隐含的模型对象. 2)调用所有方法级的 标注了 @ModelAttribute 的方法,并将方法返回值添加到隐含的模型对象中. ...

  2. hdu 4374 单调队列

    求一个最大k连续的子序列和   单调队列 #include<stdio.h> #include<string.h> #include<iostream> using ...

  3. CSS position财产

    CSS在position位置信息要素用于表示属性. 有三个起飞值:static, absolute, relative. 假设元件不显式配置position财产,该元素默认position 值至sta ...

  4. 用SendNotifyMessage代替PostMessage避免消息丢失(WIN7下消息队列的默认长度是10000,队列满后消息将被丢弃)

    大家都知道PostMessage会丢消息,但是消息队列的大小是多少呢,下面做了一个测试. 代码:   1 unit Unit1; 2 3 interface 4 5 uses 6 Windows, M ...

  5. InitializeComponent无法识别的问题

    学习Xamarin官方文档的时候,Xamarin.Forms的开始篇一直在用ContentPage讲解自己一直是创建Page,然后手动修改成继承于ContentPage,然后InitializeCom ...

  6. BackgroundWorker使用

    using System.ComponentModel; private BackgroundWorker worker;  worker = new BackgroundWorker(); work ...

  7. css3如何让div一直循环自转圈,附带:网络请求通知图片一直在转圈实例

    css3如何让div一直循环自转圈 代码如下: div{ -webkit-transition-property: -webkit-transform; -webkit-transition-dura ...

  8. How do you create a DynamicResourceBinding that supports Converters, StringFormat?

    原文 How do you create a DynamicResourceBinding that supports Converters, StringFormat? 2 down vote ac ...

  9. C# Newtonsoft.Json JObject移除属性,在序列化时忽略

    原文 C# Newtonsoft.Json JObject移除属性,在序列化时忽略 一.针对 单个 对象移除属性,序列化时忽略处理 JObject实例的 Remove() 方法,可以在 指定序列化时移 ...

  10. mysql 更改root密码

    mysql 更改root密码,有很多种,网上也有很多记录,这里只是做个记录,以后可以看看,只记录两种自己常用的方法. 1.改表法,登录到数据库,切换到:mysql数据库,update user set ...