1. /*
  2. * 切片函数,非常重要,这里一定要牢记beginIndex是开始位置,endIndex是结束位置,区别于以前学的offset是开始位置,而count或length是个数和长度
  3. * 比如说,new String("abcdefg",1,3)得到的是bcd
  4. * 而 "abcdefg".substring(1,3)得到的是bc,也就是下标为1和2的俩个字符,并不包括c
  5. */
  6. public String substring(int beginIndex) {
  7. if (beginIndex < 0) {
  8. throw new StringIndexOutOfBoundsException(beginIndex);
  9. }
  10. int subLen = value.length - beginIndex;
  11. if (subLen < 0) {
  12. throw new StringIndexOutOfBoundsException(subLen);
  13. }
  14. return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
  15. }
  16. public String substring(int beginIndex, int endIndex) {
  17. if (beginIndex < 0) {
  18. throw new StringIndexOutOfBoundsException(beginIndex);
  19. }
  20. if (endIndex > value.length) {
  21. throw new StringIndexOutOfBoundsException(endIndex);
  22. }
  23. int subLen = endIndex - beginIndex;
  24. if (subLen < 0) {
  25. throw new StringIndexOutOfBoundsException(subLen);
  26. }
  27. return ((beginIndex == 0) && (endIndex == value.length)) ? this : new String(value, beginIndex, subLen);
  28. }
  29.  
  30. /*
  31. * 返回的是一个字符序列CharSequence,而CharSequence是一个接口,所有这里需要的是CharSequence的实现类
  32. * 而String实现的最后一个接口就是CharSequence,所以其实这里返回的就是String对象
  33. * 但是这是一个多态对象,他能调用的方法只有CharSequence接口中的几个,所以此方法没用,除非程序就需要一个CharSequence对象
  34. *
  35. */
  36. public CharSequence subSequence(int beginIndex, int endIndex) {
  37. return this.substring(beginIndex, endIndex);
  38. }
  39.  
  40. /*
  41. * 将指定的字符串连接到该字符串的末尾。 如果参数字符串的长度为0 ,则返回此String对象。
  42. * 这里使用了new String(buf, true)
  43. * 否则,返回一个String对象,表示一个字符序列,该字符序列是由该String对象表示的字符序列与由参数字符串表示的字符序列的级联。
  44. * 如果需要大量的字符串拼接,请使用StringBuffer和StringBuilder
  45. */
  46. public String concat(String str) {
  47. int otherLen = str.length();
  48. if (otherLen == 0) {
  49. return this;
  50. }
  51. int len = value.length;
  52. char buf[] = Arrays.copyOf(value, len + otherLen);
  53. str.getChars(buf, len);
  54. return new String(buf, true);
  55. }
  56.  
  57. /*
  58. * 判断此字符串是否匹配指定的regaex正则表达式,正则表达式有些复杂,需要一章来叙述,这里不做赘述
  59. */
  60. public boolean matches(String regex) {
  61. return Pattern.matches(regex, this);
  62. }
  63.  
  64. /*
  65. * 判断此字符串是否包含指定的字符序列CharSequence,CharSequence在上面已经讲过了
  66. */
  67. public boolean contains(CharSequence s) {
  68. return indexOf(s.toString()) > -1;
  69. }
  70. /*
  71. * 替换字符串中的某个字符,注意参数都是字符char类型
  72. * 例如:"gollong".replace("o","")的结果为"gllng"
  73. */
  74. public String replace(char oldChar, char newChar) {
  75. if (oldChar != newChar) {
  76. int len = value.length;
  77. int i = -1;
  78. char[] val = value; /* avoid getfield opcode */
  79.  
  80. while (++i < len) {
  81. if (val[i] == oldChar) {
  82. break;
  83. }
  84. }
  85. if (i < len) {
  86. char buf[] = new char[len];
  87. for (int j = 0; j < i; j++) {
  88. buf[j] = val[j];
  89. }
  90. while (i < len) {
  91. char c = val[i];
  92. buf[i] = (c == oldChar) ? newChar : c;
  93. i++;
  94. }
  95. return new String(buf, true);
  96. }
  97. }
  98. return this;
  99. }
  100.  
  101. /*
  102. * 替换字符串中的字字符串,识别方式为正则表达式
  103. * replaceFirst只替换第一个
  104. * replaceAll为全部替换
  105. */
  106. public String replaceFirst(String regex, String replacement) {
  107. return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
  108. }
  109. public String replaceAll(String regex, String replacement) {
  110. return Pattern.compile(regex).matcher(this).replaceAll(replacement);
  111. }
  112. public String replace(CharSequence target, CharSequence replacement) {
  113. return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(this)
  114. .replaceAll(Matcher.quoteReplacement(replacement.toString()));
  115. }
  116.  
  117. /*
  118. * 切割字符串,形参regex是一个正则表达式。limit用于限制String[]的长度
  119. * 例如,字符串"boo:and:foo"使用以下参数产生以下结果:
  120. * Regex Limit Result
  121. * : 2 { "boo", "and:foo" }
  122. * : 5 { "boo", "and", "foo" }
  123. * : -2 { "boo", "and", "foo" }
  124. * o 5 { "b", "", ":and:f", "", "" }
  125. * o -2 { "b", "", ":and:f", "", "" }
  126. * o 0 { "b", "", ":and:f" }
  127.  
  128. */
  129. public String[] split(String regex, int limit) {
  130. char ch = 0;
  131. if (((regex.value.length == 1 && ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1)
  132. || (regex.length() == 2 && regex.charAt(0) == '\\' && (((ch = regex.charAt(1)) - '0') | ('9' - ch)) < 0
  133. && ((ch - 'a') | ('z' - ch)) < 0 && ((ch - 'A') | ('Z' - ch)) < 0))
  134. && (ch < Character.MIN_HIGH_SURROGATE || ch > Character.MAX_LOW_SURROGATE)) {
  135. int off = 0;
  136. int next = 0;
  137. boolean limited = limit > 0;
  138. ArrayList<String> list = new ArrayList<>();
  139. while ((next = indexOf(ch, off)) != -1) {
  140. if (!limited || list.size() < limit - 1) {
  141. list.add(substring(off, next));
  142. off = next + 1;
  143. } else { // last one
  144. // assert (list.size() == limit - 1);
  145. list.add(substring(off, value.length));
  146. off = value.length;
  147. break;
  148. }
  149. }
  150. // If no match was found, return this
  151. if (off == 0)
  152. return new String[] { this };
  153.  
  154. // Add remaining segment
  155. if (!limited || list.size() < limit)
  156. list.add(substring(off, value.length));
  157.  
  158. // Construct result
  159. int resultSize = list.size();
  160. if (limit == 0) {
  161. while (resultSize > 0 && list.get(resultSize - 1).length() == 0) {
  162. resultSize--;
  163. }
  164. }
  165. String[] result = new String[resultSize];
  166. return list.subList(0, resultSize).toArray(result);
  167. }
  168. return Pattern.compile(regex).split(this, limit);
  169. }
  170.  
  171. public String[] split(String regex) {
  172. return split(regex, 0);
  173. }
  174.  
  175. /*
  176. * 去掉字符串两端的空格,很有用的小方法
  177. */
  178. public String trim() {
  179. int len = value.length;
  180. int st = 0;
  181. char[] val = value; /* avoid getfield opcode */
  182.  
  183. while ((st < len) && (val[st] <= ' ')) {
  184. st++;
  185. }
  186. while ((st < len) && (val[len - 1] <= ' ')) {
  187. len--;
  188. }
  189. return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
  190. }
  191.  
  192. /*
  193. * toString返回这个对象本身,
  194. * 重点:我们总以为直接输出一个字符串对象可以打印其char数组的内容是因为String重写了toString方法
  195. * 我们认为System.out.println(str)就是System.out.println(str.toString())
  196. * 其实不是的,我们很清楚的看到了,toString方法就是返回一个String对象,并不是遍历
  197. * 于是乎我们得到了一个结论:
  198. * System.out.println(str.toString())就是System.out.println(str)他们都依赖于String的特殊的实现机制
  199. * 这个机制就是:String s = "gollopng"就是创造对象并实例化
  200. * System.out.println(str)就是直接遍历输出
  201. */
  202. public String toString() {
  203. return this;
  204. }
  205.  
  206. /*
  207. * 将字符串转换为char数组,此时联想一下charAt方法,不要记混了
  208. */
  209. public char[] toCharArray() {
  210. // Cannot use Arrays.copyOf because of class initialization order issues
  211. char result[] = new char[value.length];
  212. System.arraycopy(value, 0, result, 0, value.length);
  213. return result;
  214. }
  215.  
  216. /*
  217. * 返回字符串对象的规范表示,它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。
  218. * 尽管在输出中调用intern方法并没有什么效果,但是实际上后台这个方法会做一系列的动作和操作。在调用”gollong”.intern()方法的时候会返回”gollong”,
  219. * 但是这个方法会首先检查字符串常量池中是否有”gollong”这个字符串,如果存在则该引用指向它,否则就将这个字符添加到字符串池中,然会再指向。
  220. */
  221. public native String intern();
  222.  
  223. /*
  224. * 返回一个新的字符串,由 CharSequence elements的副本组成,并附有指定的delimiter的 delimiter
  225. */
  226. public static String join(CharSequence delimiter, CharSequence... elements) {
  227. Objects.requireNonNull(delimiter);
  228. Objects.requireNonNull(elements);
  229. // Number of elements not likely worth Arrays.stream overhead.
  230. StringJoiner joiner = new StringJoiner(delimiter);
  231. for (CharSequence cs : elements) {
  232. joiner.add(cs);
  233. }
  234. return joiner.toString();
  235. }
  236.  
  237. /*
  238. * 返回一个新 String的副本组成 CharSequence elements与指定的副本一起加入 delimiter 。
  239. */
  240. public static String join(CharSequence delimiter, Iterable<? extends CharSequence> elements) {
  241. Objects.requireNonNull(delimiter);
  242. Objects.requireNonNull(elements);
  243. StringJoiner joiner = new StringJoiner(delimiter);
  244. for (CharSequence cs : elements) {
  245. joiner.add(cs);
  246. }
  247. return joiner.toString();
  248. }
  249.  
  250. /*
  251. * toLowerCase(Locale locale):将字符串中所有小写字符转换为大写,其中locale用于指定自己的规则
  252. * toUpperCase(Locale locale):将字符串中所有大写字符转换为小写,其中locale用于指定自己的规则
  253. */
  254. public String toLowerCase(Locale locale) {
  255. if (locale == null) {
  256. throw new NullPointerException();
  257. }
  258.  
  259. int firstUpper;
  260. final int len = value.length;
  261.  
  262. /* Now check if there are any characters that need to be changed. */
  263. scan: {
  264. for (firstUpper = 0; firstUpper < len;) {
  265. char c = value[firstUpper];
  266. if ((c >= Character.MIN_HIGH_SURROGATE) && (c <= Character.MAX_HIGH_SURROGATE)) {
  267. int supplChar = codePointAt(firstUpper);
  268. if (supplChar != Character.toLowerCase(supplChar)) {
  269. break scan;
  270. }
  271. firstUpper += Character.charCount(supplChar);
  272. } else {
  273. if (c != Character.toLowerCase(c)) {
  274. break scan;
  275. }
  276. firstUpper++;
  277. }
  278. }
  279. return this;
  280. }
  281.  
  282. char[] result = new char[len];
  283. int resultOffset = 0;
  284. System.arraycopy(value, 0, result, 0, firstUpper);
  285.  
  286. String lang = locale.getLanguage();
  287. boolean localeDependent = (lang == "tr" || lang == "az" || lang == "lt");
  288. char[] lowerCharArray;
  289. int lowerChar;
  290. int srcChar;
  291. int srcCount;
  292. for (int i = firstUpper; i < len; i += srcCount) {
  293. srcChar = (int) value[i];
  294. if ((char) srcChar >= Character.MIN_HIGH_SURROGATE && (char) srcChar <= Character.MAX_HIGH_SURROGATE) {
  295. srcChar = codePointAt(i);
  296. srcCount = Character.charCount(srcChar);
  297. } else {
  298. srcCount = 1;
  299. }
  300. if (localeDependent || srcChar == '\u03A3' || // GREEK CAPITAL LETTER SIGMA
  301. srcChar == '\u0130') { // LATIN CAPITAL LETTER I WITH DOT ABOVE
  302. lowerChar = ConditionalSpecialCasing.toLowerCaseEx(this, i, locale);
  303. } else {
  304. lowerChar = Character.toLowerCase(srcChar);
  305. }
  306. if ((lowerChar == Character.ERROR) || (lowerChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
  307. if (lowerChar == Character.ERROR) {
  308. lowerCharArray = ConditionalSpecialCasing.toLowerCaseCharArray(this, i, locale);
  309. } else if (srcCount == 2) {
  310. resultOffset += Character.toChars(lowerChar, result, i + resultOffset) - srcCount;
  311. continue;
  312. } else {
  313. lowerCharArray = Character.toChars(lowerChar);
  314. }
  315.  
  316. /* Grow result if needed */
  317. int mapLen = lowerCharArray.length;
  318. if (mapLen > srcCount) {
  319. char[] result2 = new char[result.length + mapLen - srcCount];
  320. System.arraycopy(result, 0, result2, 0, i + resultOffset);
  321. result = result2;
  322. }
  323. for (int x = 0; x < mapLen; ++x) {
  324. result[i + resultOffset + x] = lowerCharArray[x];
  325. }
  326. resultOffset += (mapLen - srcCount);
  327. } else {
  328. result[i + resultOffset] = (char) lowerChar;
  329. }
  330. }
  331. return new String(result, 0, len + resultOffset);
  332. }
  333. public String toLowerCase() {
  334. return toLowerCase(Locale.getDefault());
  335. }
  336. public String toUpperCase(Locale locale) {
  337. if (locale == null) {
  338. throw new NullPointerException();
  339. }
  340. int firstLower;
  341. final int len = value.length;
  342. scan: {
  343. for (firstLower = 0; firstLower < len;) {
  344. int c = (int) value[firstLower];
  345. int srcCount;
  346. if ((c >= Character.MIN_HIGH_SURROGATE) && (c <= Character.MAX_HIGH_SURROGATE)) {
  347. c = codePointAt(firstLower);
  348. srcCount = Character.charCount(c);
  349. } else {
  350. srcCount = 1;
  351. }
  352. int upperCaseChar = Character.toUpperCaseEx(c);
  353. if ((upperCaseChar == Character.ERROR) || (c != upperCaseChar)) {
  354. break scan;
  355. }
  356. firstLower += srcCount;
  357. }
  358. return this;
  359. }
  360. int resultOffset = 0;
  361. char[] result = new char[len];
  362. System.arraycopy(value, 0, result, 0, firstLower);
  363.  
  364. String lang = locale.getLanguage();
  365. boolean localeDependent = (lang == "tr" || lang == "az" || lang == "lt");
  366. char[] upperCharArray;
  367. int upperChar;
  368. int srcChar;
  369. int srcCount;
  370. for (int i = firstLower; i < len; i += srcCount) {
  371. srcChar = (int) value[i];
  372. if ((char) srcChar >= Character.MIN_HIGH_SURROGATE && (char) srcChar <= Character.MAX_HIGH_SURROGATE) {
  373. srcChar = codePointAt(i);
  374. srcCount = Character.charCount(srcChar);
  375. } else {
  376. srcCount = 1;
  377. }
  378. if (localeDependent) {
  379. upperChar = ConditionalSpecialCasing.toUpperCaseEx(this, i, locale);
  380. } else {
  381. upperChar = Character.toUpperCaseEx(srcChar);
  382. }
  383. if ((upperChar == Character.ERROR) || (upperChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
  384. if (upperChar == Character.ERROR) {
  385. if (localeDependent) {
  386. upperCharArray = ConditionalSpecialCasing.toUpperCaseCharArray(this, i, locale);
  387. } else {
  388. upperCharArray = Character.toUpperCaseCharArray(srcChar);
  389. }
  390. } else if (srcCount == 2) {
  391. resultOffset += Character.toChars(upperChar, result, i + resultOffset) - srcCount;
  392. continue;
  393. } else {
  394. upperCharArray = Character.toChars(upperChar);
  395. }
  396. int mapLen = upperCharArray.length;
  397. if (mapLen > srcCount) {
  398. char[] result2 = new char[result.length + mapLen - srcCount];
  399. System.arraycopy(result, 0, result2, 0, i + resultOffset);
  400. result = result2;
  401. }
  402. for (int x = 0; x < mapLen; ++x) {
  403. result[i + resultOffset + x] = upperCharArray[x];
  404. }
  405. resultOffset += (mapLen - srcCount);
  406. } else {
  407. result[i + resultOffset] = (char) upperChar;
  408. }
  409. }
  410. return new String(result, 0, len + resultOffset);
  411. }
  412.  
  413. public String toUpperCase() {
  414. return toUpperCase(Locale.getDefault());
  415. }
  416.  
  417. /*
  418. * 使用指定的格式字符串和参数返回格式化的字符串。 Object... args是可变参数
  419. */
  420. public static String format(String format, Object... args) {
  421. return new Formatter().format(format, args).toString();
  422. }
  423.  
  424. /*
  425. * 使用指定的区域设置,格式字符串和参数返回格式化的字符串。
  426. */
  427. public static String format(Locale l, String format, Object... args) {
  428. return new Formatter(l).format(format, args).toString();
  429. }
  430.  
  431. /*
  432. * 下面是String通过静态方法将其他类型转换为字符串
  433. * 总结:将其他类型转换为字符串有三种方法
  434. * 1.String的构造器:可以转换byte[]、char[]、int[]
  435. * 2.String的静态方法valueOf:可以转换Object对象、char[]、boolean、char、int、long、float、double
  436. * 3.其他类型的toString方法:只要是重写了toString,就可以转换
  437. */
  438. public static String valueOf(Object obj) {
  439. return (obj == null) ? "null" : obj.toString();
  440. }
  441. public static String valueOf(char data[]) {
  442. return new String(data);
  443. }
  444. public static String valueOf(char data[], int offset, int count) {
  445. return new String(data, offset, count);
  446. }
  447.  
  448. public static String copyValueOf(char data[], int offset, int count) {
  449. return new String(data, offset, count);
  450. }
  451.  
  452. public static String copyValueOf(char data[]) {
  453. return new String(data);
  454. }
  455.  
  456. public static String valueOf(boolean b) {
  457. return b ? "true" : "false";
  458. }
  459. public static String valueOf(char c) {
  460. char data[] = { c };
  461. return new String(data, true);
  462. }
  463. public static String valueOf(int i) {
  464. return Integer.toString(i);
  465. }
  466. public static String valueOf(long l) {
  467. return Long.toString(l);
  468. }
  469. public static String valueOf(float f) {
  470. return Float.toString(f);
  471. }
  472. public static String valueOf(double d) {
  473. return Double.toString(d);
  474. }

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

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

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

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

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

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

    上一节主要介绍了String类的一些构造方法,主要分为四类 无参构造器:String(),创建一个空字符串"",区别于null字符串,""已经初始化,null并 ...

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

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

  5. Java源码解析——集合框架(五)——HashMap源码分析

    HashMap源码分析 HashMap的底层实现是面试中问到最多的,其原理也更加复杂,涉及的知识也越多,在项目中的使用也最多.因此清晰分析出其底层源码对于深刻理解其实现有重要的意义,jdk1.8之后其 ...

  6. java源码解析之Object类

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

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

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

  8. 【Java源码解析】Thread

    简介 线程本质上也是进程.线程机制提供了在同一程序内共享内存地址空间运行的一组线程.对于内核来讲,它就是进程,只是该进程和其他一下进程共享某些资源,比如地址空间.在Java语言里,Thread类封装了 ...

  9. AOP源码解析:AspectJAwareAdvisorAutoProxyCreator类的介绍

    AspectJAwareAdvisorAutoProxyCreator 的类图 上图中一些 类/接口 的介绍: AspectJAwareAdvisorAutoProxyCreator : 公开了Asp ...

随机推荐

  1. 各种图示的介绍及绘制(boxplot、stem)

    1. 箱线图(boxplot) 也叫作箱形图: 一种用作显示一组数据分散情况资料的统计图.因形状如箱子而得名.在各种领域也经常被使用,常见于品质管理. 主要包含六个数据节点,将一组数据从大到小排列,分 ...

  2. 使用带ParserContext参数的Xaml.Load方法

    原文:使用带ParserContext参数的Xaml.Load方法 如果一段XAML中存在一个标记需要从外部命名空间中解析, 就需要用到ParserContext类,  具体用法如下: Normal ...

  3. Atitit.Gui控制and面板----db数据库领域----- .比较数据库同步工具 vOa

    Atitit.Gui控制and面板----db数据库区----- .数据库比較同步工具 vOa 1. 咨微海信数据库应用 工具 1 2. 数据库比較工具 StarInix SQL Compare    ...

  4. wxWidgets编译和在VC 6.0中的配置

    1. 安装  运行wxMSW-2.8.3-Setup1.exe,将之安装到不带空格符号的目录中,本例为C:/wxWidgets-2.8.3:   2. 编译和配置 (1) 用VC6.0编译  进入C: ...

  5. ImageNet 数据集

    1. top-5 error rate ImageNet 图像通常有 1000 个可能的类别,对每幅图像你可以猜 5 次结果(即同时预测5个类别标签),当其中有任何一次预测对了,结果都算对(事实上一个 ...

  6. windows消息值全部定义,从消息值得到消息名称(系统消息定义从0到1023,从1024开始就是WM_USER,但是中间有325个WM_undefined消息,估计是备用,另外各控件都有一些reserved消息,也是为了备用)LostSpeed

    前言 在逆向算法扫描插件时, 遇到一个windows消息值在msdn中没有定义. 去查资料, 有个老外将全部windows消息值和消息名称定义都码好了:) 写个测试程序, 封装了一个接口, 从消息值得 ...

  7. Android bluetooth介绍(两): android 蓝牙源架构和uart 至rfcomm过程

    关键词:蓝牙blueZ  UART  HCI_UART H4  HCI  L2CAP RFCOMM  版本号:基于android4.2先前版本 bluez内核:linux/linux3.08系统:an ...

  8. [解决方案]sql server复制需要有实际的服务器名称才能连接到服务器

    原文:[解决方案]sql server复制需要有实际的服务器名称才能连接到服务器 在配置数据同步的时候,要求相互同步的两台机器的数据库必须通过默认实例名称进行连接.如果你的默认实例已经删掉了,在当前实 ...

  9. 安装 VirtualBox 出现回滚,无法安装及解决方法

    原文:安装 VirtualBox 出现回滚,无法安装及解决方法 缘由:打算安装 Vagrant,因此打算安装 VirtualBox. 现象:安装 VirtualBox,进度快到最后的时候,安装程序执行 ...

  10. 为DataGridTemplateColumn设置快捷菜单

    <DataGrid.ContextMenu> <ContextMenu> <MenuItem Command="{x:Static ApplicationCom ...