java源码解析之String类(五)
- /*
- * 切片函数,非常重要,这里一定要牢记beginIndex是开始位置,endIndex是结束位置,区别于以前学的offset是开始位置,而count或length是个数和长度
- * 比如说,new String("abcdefg",1,3)得到的是bcd
- * 而 "abcdefg".substring(1,3)得到的是bc,也就是下标为1和2的俩个字符,并不包括c
- */
- public String substring(int beginIndex) {
- if (beginIndex < 0) {
- throw new StringIndexOutOfBoundsException(beginIndex);
- }
- int subLen = value.length - beginIndex;
- if (subLen < 0) {
- throw new StringIndexOutOfBoundsException(subLen);
- }
- return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
- }
- public String substring(int beginIndex, int endIndex) {
- if (beginIndex < 0) {
- throw new StringIndexOutOfBoundsException(beginIndex);
- }
- if (endIndex > value.length) {
- throw new StringIndexOutOfBoundsException(endIndex);
- }
- int subLen = endIndex - beginIndex;
- if (subLen < 0) {
- throw new StringIndexOutOfBoundsException(subLen);
- }
- return ((beginIndex == 0) && (endIndex == value.length)) ? this : new String(value, beginIndex, subLen);
- }
- /*
- * 返回的是一个字符序列CharSequence,而CharSequence是一个接口,所有这里需要的是CharSequence的实现类
- * 而String实现的最后一个接口就是CharSequence,所以其实这里返回的就是String对象
- * 但是这是一个多态对象,他能调用的方法只有CharSequence接口中的几个,所以此方法没用,除非程序就需要一个CharSequence对象
- *
- */
- public CharSequence subSequence(int beginIndex, int endIndex) {
- return this.substring(beginIndex, endIndex);
- }
- /*
- * 将指定的字符串连接到该字符串的末尾。 如果参数字符串的长度为0 ,则返回此String对象。
- * 这里使用了new String(buf, true)
- * 否则,返回一个String对象,表示一个字符序列,该字符序列是由该String对象表示的字符序列与由参数字符串表示的字符序列的级联。
- * 如果需要大量的字符串拼接,请使用StringBuffer和StringBuilder
- */
- public String concat(String str) {
- int otherLen = str.length();
- if (otherLen == 0) {
- return this;
- }
- int len = value.length;
- char buf[] = Arrays.copyOf(value, len + otherLen);
- str.getChars(buf, len);
- return new String(buf, true);
- }
- /*
- * 判断此字符串是否匹配指定的regaex正则表达式,正则表达式有些复杂,需要一章来叙述,这里不做赘述
- */
- public boolean matches(String regex) {
- return Pattern.matches(regex, this);
- }
- /*
- * 判断此字符串是否包含指定的字符序列CharSequence,CharSequence在上面已经讲过了
- */
- public boolean contains(CharSequence s) {
- return indexOf(s.toString()) > -1;
- }
- /*
- * 替换字符串中的某个字符,注意参数都是字符char类型
- * 例如:"gollong".replace("o","")的结果为"gllng"
- */
- 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;
- }
- /*
- * 替换字符串中的字字符串,识别方式为正则表达式
- * replaceFirst只替换第一个
- * replaceAll为全部替换
- */
- public String replaceFirst(String regex, String replacement) {
- return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
- }
- public String replaceAll(String regex, String replacement) {
- return Pattern.compile(regex).matcher(this).replaceAll(replacement);
- }
- public String replace(CharSequence target, CharSequence replacement) {
- return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(this)
- .replaceAll(Matcher.quoteReplacement(replacement.toString()));
- }
- /*
- * 切割字符串,形参regex是一个正则表达式。limit用于限制String[]的长度
- * 例如,字符串"boo:and:foo"使用以下参数产生以下结果:
- * Regex Limit Result
- * : 2 { "boo", "and:foo" }
- * : 5 { "boo", "and", "foo" }
- * : -2 { "boo", "and", "foo" }
- * o 5 { "b", "", ":and:f", "", "" }
- * o -2 { "b", "", ":and:f", "", "" }
- * o 0 { "b", "", ":and:f" }
- */
- public String[] split(String regex, int limit) {
- char ch = 0;
- if (((regex.value.length == 1 && ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1)
- || (regex.length() == 2 && regex.charAt(0) == '\\' && (((ch = regex.charAt(1)) - '0') | ('9' - ch)) < 0
- && ((ch - 'a') | ('z' - ch)) < 0 && ((ch - 'A') | ('Z' - ch)) < 0))
- && (ch < Character.MIN_HIGH_SURROGATE || ch > Character.MAX_LOW_SURROGATE)) {
- int off = 0;
- int next = 0;
- boolean limited = limit > 0;
- ArrayList<String> list = new ArrayList<>();
- while ((next = indexOf(ch, off)) != -1) {
- if (!limited || list.size() < limit - 1) {
- list.add(substring(off, next));
- off = next + 1;
- } else { // last one
- // assert (list.size() == limit - 1);
- list.add(substring(off, value.length));
- off = value.length;
- break;
- }
- }
- // If no match was found, return this
- if (off == 0)
- return new String[] { this };
- // Add remaining segment
- if (!limited || list.size() < limit)
- list.add(substring(off, value.length));
- // Construct result
- int resultSize = list.size();
- if (limit == 0) {
- while (resultSize > 0 && list.get(resultSize - 1).length() == 0) {
- resultSize--;
- }
- }
- String[] result = new String[resultSize];
- return list.subList(0, resultSize).toArray(result);
- }
- return Pattern.compile(regex).split(this, limit);
- }
- public String[] split(String regex) {
- return split(regex, 0);
- }
- /*
- * 去掉字符串两端的空格,很有用的小方法
- */
- public String trim() {
- int len = value.length;
- int st = 0;
- char[] val = value; /* avoid getfield opcode */
- while ((st < len) && (val[st] <= ' ')) {
- st++;
- }
- while ((st < len) && (val[len - 1] <= ' ')) {
- len--;
- }
- return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
- }
- /*
- * toString返回这个对象本身,
- * 重点:我们总以为直接输出一个字符串对象可以打印其char数组的内容是因为String重写了toString方法
- * 我们认为System.out.println(str)就是System.out.println(str.toString())
- * 其实不是的,我们很清楚的看到了,toString方法就是返回一个String对象,并不是遍历
- * 于是乎我们得到了一个结论:
- * System.out.println(str.toString())就是System.out.println(str)他们都依赖于String的特殊的实现机制
- * 这个机制就是:String s = "gollopng"就是创造对象并实例化
- * System.out.println(str)就是直接遍历输出
- */
- public String toString() {
- return this;
- }
- /*
- * 将字符串转换为char数组,此时联想一下charAt方法,不要记混了
- */
- public char[] toCharArray() {
- // Cannot use Arrays.copyOf because of class initialization order issues
- char result[] = new char[value.length];
- System.arraycopy(value, 0, result, 0, value.length);
- return result;
- }
- /*
- * 返回字符串对象的规范表示,它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。
- * 尽管在输出中调用intern方法并没有什么效果,但是实际上后台这个方法会做一系列的动作和操作。在调用”gollong”.intern()方法的时候会返回”gollong”,
- * 但是这个方法会首先检查字符串常量池中是否有”gollong”这个字符串,如果存在则该引用指向它,否则就将这个字符添加到字符串池中,然会再指向。
- */
- public native String intern();
- /*
- * 返回一个新的字符串,由 CharSequence elements的副本组成,并附有指定的delimiter的 delimiter
- */
- public static String join(CharSequence delimiter, CharSequence... elements) {
- Objects.requireNonNull(delimiter);
- Objects.requireNonNull(elements);
- // Number of elements not likely worth Arrays.stream overhead.
- StringJoiner joiner = new StringJoiner(delimiter);
- for (CharSequence cs : elements) {
- joiner.add(cs);
- }
- return joiner.toString();
- }
- /*
- * 返回一个新 String的副本组成 CharSequence elements与指定的副本一起加入 delimiter 。
- */
- public static String join(CharSequence delimiter, Iterable<? extends CharSequence> elements) {
- Objects.requireNonNull(delimiter);
- Objects.requireNonNull(elements);
- StringJoiner joiner = new StringJoiner(delimiter);
- for (CharSequence cs : elements) {
- joiner.add(cs);
- }
- return joiner.toString();
- }
- /*
- * toLowerCase(Locale locale):将字符串中所有小写字符转换为大写,其中locale用于指定自己的规则
- * toUpperCase(Locale locale):将字符串中所有大写字符转换为小写,其中locale用于指定自己的规则
- */
- public String toLowerCase(Locale locale) {
- if (locale == null) {
- throw new NullPointerException();
- }
- int firstUpper;
- final int len = value.length;
- /* Now check if there are any characters that need to be changed. */
- scan: {
- for (firstUpper = 0; firstUpper < len;) {
- char c = value[firstUpper];
- if ((c >= Character.MIN_HIGH_SURROGATE) && (c <= Character.MAX_HIGH_SURROGATE)) {
- int supplChar = codePointAt(firstUpper);
- if (supplChar != Character.toLowerCase(supplChar)) {
- break scan;
- }
- firstUpper += Character.charCount(supplChar);
- } else {
- if (c != Character.toLowerCase(c)) {
- break scan;
- }
- firstUpper++;
- }
- }
- return this;
- }
- char[] result = new char[len];
- int resultOffset = 0;
- System.arraycopy(value, 0, result, 0, firstUpper);
- String lang = locale.getLanguage();
- boolean localeDependent = (lang == "tr" || lang == "az" || lang == "lt");
- char[] lowerCharArray;
- int lowerChar;
- int srcChar;
- int srcCount;
- for (int i = firstUpper; i < len; i += srcCount) {
- srcChar = (int) value[i];
- if ((char) srcChar >= Character.MIN_HIGH_SURROGATE && (char) srcChar <= Character.MAX_HIGH_SURROGATE) {
- srcChar = codePointAt(i);
- srcCount = Character.charCount(srcChar);
- } else {
- srcCount = 1;
- }
- if (localeDependent || srcChar == '\u03A3' || // GREEK CAPITAL LETTER SIGMA
- srcChar == '\u0130') { // LATIN CAPITAL LETTER I WITH DOT ABOVE
- lowerChar = ConditionalSpecialCasing.toLowerCaseEx(this, i, locale);
- } else {
- lowerChar = Character.toLowerCase(srcChar);
- }
- if ((lowerChar == Character.ERROR) || (lowerChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
- if (lowerChar == Character.ERROR) {
- lowerCharArray = ConditionalSpecialCasing.toLowerCaseCharArray(this, i, locale);
- } else if (srcCount == 2) {
- resultOffset += Character.toChars(lowerChar, result, i + resultOffset) - srcCount;
- continue;
- } else {
- lowerCharArray = Character.toChars(lowerChar);
- }
- /* Grow result if needed */
- int mapLen = lowerCharArray.length;
- if (mapLen > srcCount) {
- char[] result2 = new char[result.length + mapLen - srcCount];
- System.arraycopy(result, 0, result2, 0, i + resultOffset);
- result = result2;
- }
- for (int x = 0; x < mapLen; ++x) {
- result[i + resultOffset + x] = lowerCharArray[x];
- }
- resultOffset += (mapLen - srcCount);
- } else {
- result[i + resultOffset] = (char) lowerChar;
- }
- }
- return new String(result, 0, len + resultOffset);
- }
- public String toLowerCase() {
- return toLowerCase(Locale.getDefault());
- }
- public String toUpperCase(Locale locale) {
- if (locale == null) {
- throw new NullPointerException();
- }
- int firstLower;
- final int len = value.length;
- scan: {
- for (firstLower = 0; firstLower < len;) {
- int c = (int) value[firstLower];
- int srcCount;
- if ((c >= Character.MIN_HIGH_SURROGATE) && (c <= Character.MAX_HIGH_SURROGATE)) {
- c = codePointAt(firstLower);
- srcCount = Character.charCount(c);
- } else {
- srcCount = 1;
- }
- int upperCaseChar = Character.toUpperCaseEx(c);
- if ((upperCaseChar == Character.ERROR) || (c != upperCaseChar)) {
- break scan;
- }
- firstLower += srcCount;
- }
- return this;
- }
- int resultOffset = 0;
- char[] result = new char[len];
- System.arraycopy(value, 0, result, 0, firstLower);
- String lang = locale.getLanguage();
- boolean localeDependent = (lang == "tr" || lang == "az" || lang == "lt");
- char[] upperCharArray;
- int upperChar;
- int srcChar;
- int srcCount;
- for (int i = firstLower; i < len; i += srcCount) {
- srcChar = (int) value[i];
- if ((char) srcChar >= Character.MIN_HIGH_SURROGATE && (char) srcChar <= Character.MAX_HIGH_SURROGATE) {
- srcChar = codePointAt(i);
- srcCount = Character.charCount(srcChar);
- } else {
- srcCount = 1;
- }
- if (localeDependent) {
- upperChar = ConditionalSpecialCasing.toUpperCaseEx(this, i, locale);
- } else {
- upperChar = Character.toUpperCaseEx(srcChar);
- }
- if ((upperChar == Character.ERROR) || (upperChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
- if (upperChar == Character.ERROR) {
- if (localeDependent) {
- upperCharArray = ConditionalSpecialCasing.toUpperCaseCharArray(this, i, locale);
- } else {
- upperCharArray = Character.toUpperCaseCharArray(srcChar);
- }
- } else if (srcCount == 2) {
- resultOffset += Character.toChars(upperChar, result, i + resultOffset) - srcCount;
- continue;
- } else {
- upperCharArray = Character.toChars(upperChar);
- }
- int mapLen = upperCharArray.length;
- if (mapLen > srcCount) {
- char[] result2 = new char[result.length + mapLen - srcCount];
- System.arraycopy(result, 0, result2, 0, i + resultOffset);
- result = result2;
- }
- for (int x = 0; x < mapLen; ++x) {
- result[i + resultOffset + x] = upperCharArray[x];
- }
- resultOffset += (mapLen - srcCount);
- } else {
- result[i + resultOffset] = (char) upperChar;
- }
- }
- return new String(result, 0, len + resultOffset);
- }
- public String toUpperCase() {
- return toUpperCase(Locale.getDefault());
- }
- /*
- * 使用指定的格式字符串和参数返回格式化的字符串。 Object... args是可变参数
- */
- public static String format(String format, Object... args) {
- return new Formatter().format(format, args).toString();
- }
- /*
- * 使用指定的区域设置,格式字符串和参数返回格式化的字符串。
- */
- public static String format(Locale l, String format, Object... args) {
- return new Formatter(l).format(format, args).toString();
- }
- /*
- * 下面是String通过静态方法将其他类型转换为字符串
- * 总结:将其他类型转换为字符串有三种方法
- * 1.String的构造器:可以转换byte[]、char[]、int[]
- * 2.String的静态方法valueOf:可以转换Object对象、char[]、boolean、char、int、long、float、double
- * 3.其他类型的toString方法:只要是重写了toString,就可以转换
- */
- public static String valueOf(Object obj) {
- return (obj == null) ? "null" : obj.toString();
- }
- public static String valueOf(char data[]) {
- return new String(data);
- }
- public static String valueOf(char data[], int offset, int count) {
- return new String(data, offset, count);
- }
- public static String copyValueOf(char data[], int offset, int count) {
- return new String(data, offset, count);
- }
- public static String copyValueOf(char data[]) {
- return new String(data);
- }
- public static String valueOf(boolean b) {
- return b ? "true" : "false";
- }
- public static String valueOf(char c) {
- char data[] = { c };
- return new String(data, true);
- }
- public static String valueOf(int i) {
- return Integer.toString(i);
- }
- public static String valueOf(long l) {
- return Long.toString(l);
- }
- public static String valueOf(float f) {
- return Float.toString(f);
- }
- public static String valueOf(double d) {
- return Double.toString(d);
- }
java源码解析之String类(五)的更多相关文章
- java源码解析之String类(一)
String是我们接触最多的类,无论是学习中还是工作中,基本每天都会和字符串打交道,从字符串本身的各种拼接.切片.变形,再到和其他基本数据类型的转换,几乎无时无刻都在使用它,今天就让我们揭开Strin ...
- java源码解析之String类(三)
上一节我们主要讲了String类的一些不是很常用的方法,其中需要掌握的如下,我就不再赘述了 public int length() public boolean isEmpty() public by ...
- java源码解析之String类(二)
上一节主要介绍了String类的一些构造方法,主要分为四类 无参构造器:String(),创建一个空字符串"",区别于null字符串,""已经初始化,null并 ...
- java源码解析之String类(四)
/* * 返回指定字符第一次出现的字符串内的索引 */ public int indexOf(int ch) { return indexOf(ch, 0); } /* * 返回指定字符第一次出现的字 ...
- Java源码解析——集合框架(五)——HashMap源码分析
HashMap源码分析 HashMap的底层实现是面试中问到最多的,其原理也更加复杂,涉及的知识也越多,在项目中的使用也最多.因此清晰分析出其底层源码对于深刻理解其实现有重要的意义,jdk1.8之后其 ...
- java源码解析之Object类
一.Object类概述 Object类是java中类层次的根,是所有类的基类.在编译时会自动导入.Object中的方法如下: 二.方法详解 Object的方法可以分成两类,一类是被关键字fin ...
- [Java源码解析] -- String类的compareTo(String otherString)方法的源码解析
String类下的compareTo(String otherString)方法的源码解析 一. 前言 近日研究了一下String类的一些方法, 通过查看源码, 对一些常用的方法也有了更透彻的认识, ...
- 【Java源码解析】Thread
简介 线程本质上也是进程.线程机制提供了在同一程序内共享内存地址空间运行的一组线程.对于内核来讲,它就是进程,只是该进程和其他一下进程共享某些资源,比如地址空间.在Java语言里,Thread类封装了 ...
- AOP源码解析:AspectJAwareAdvisorAutoProxyCreator类的介绍
AspectJAwareAdvisorAutoProxyCreator 的类图 上图中一些 类/接口 的介绍: AspectJAwareAdvisorAutoProxyCreator : 公开了Asp ...
随机推荐
- 各种图示的介绍及绘制(boxplot、stem)
1. 箱线图(boxplot) 也叫作箱形图: 一种用作显示一组数据分散情况资料的统计图.因形状如箱子而得名.在各种领域也经常被使用,常见于品质管理. 主要包含六个数据节点,将一组数据从大到小排列,分 ...
- 使用带ParserContext参数的Xaml.Load方法
原文:使用带ParserContext参数的Xaml.Load方法 如果一段XAML中存在一个标记需要从外部命名空间中解析, 就需要用到ParserContext类, 具体用法如下: Normal ...
- Atitit.Gui控制and面板----db数据库领域----- .比较数据库同步工具 vOa
Atitit.Gui控制and面板----db数据库区----- .数据库比較同步工具 vOa 1. 咨微海信数据库应用 工具 1 2. 数据库比較工具 StarInix SQL Compare ...
- wxWidgets编译和在VC 6.0中的配置
1. 安装 运行wxMSW-2.8.3-Setup1.exe,将之安装到不带空格符号的目录中,本例为C:/wxWidgets-2.8.3: 2. 编译和配置 (1) 用VC6.0编译 进入C: ...
- ImageNet 数据集
1. top-5 error rate ImageNet 图像通常有 1000 个可能的类别,对每幅图像你可以猜 5 次结果(即同时预测5个类别标签),当其中有任何一次预测对了,结果都算对(事实上一个 ...
- windows消息值全部定义,从消息值得到消息名称(系统消息定义从0到1023,从1024开始就是WM_USER,但是中间有325个WM_undefined消息,估计是备用,另外各控件都有一些reserved消息,也是为了备用)LostSpeed
前言 在逆向算法扫描插件时, 遇到一个windows消息值在msdn中没有定义. 去查资料, 有个老外将全部windows消息值和消息名称定义都码好了:) 写个测试程序, 封装了一个接口, 从消息值得 ...
- Android bluetooth介绍(两): android 蓝牙源架构和uart 至rfcomm过程
关键词:蓝牙blueZ UART HCI_UART H4 HCI L2CAP RFCOMM 版本号:基于android4.2先前版本 bluez内核:linux/linux3.08系统:an ...
- [解决方案]sql server复制需要有实际的服务器名称才能连接到服务器
原文:[解决方案]sql server复制需要有实际的服务器名称才能连接到服务器 在配置数据同步的时候,要求相互同步的两台机器的数据库必须通过默认实例名称进行连接.如果你的默认实例已经删掉了,在当前实 ...
- 安装 VirtualBox 出现回滚,无法安装及解决方法
原文:安装 VirtualBox 出现回滚,无法安装及解决方法 缘由:打算安装 Vagrant,因此打算安装 VirtualBox. 现象:安装 VirtualBox,进度快到最后的时候,安装程序执行 ...
- 为DataGridTemplateColumn设置快捷菜单
<DataGrid.ContextMenu> <ContextMenu> <MenuItem Command="{x:Static ApplicationCom ...