/*
* 切片函数,非常重要,这里一定要牢记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类(五)的更多相关文章

  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. Information centric network (icn) node based on switch and network process using the node

    The present invention relates to an apparatus for supporting information centric networking. An info ...

  2. JS 禁止IE用右键

    <!--组合键: -->IE的键盘监听最多只能作用于document上(window我试过不行)如果内嵌了iframe并且你的焦点在iframe上,那么按键无效 这里我用CTRL+Q写的例 ...

  3. Windows7配置QT-Android开发环境!

    配置QT5.2.0-Android版本: 进行windows7下的软件开发~不用使用eclipse开发android软件,配置之后就可以向写C++代码一样,去写APP在Android手机上去运行了! ...

  4. c#开发移动APP-Xamarin入门扩展剖析

    原文:c#开发移动APP-Xamarin入门扩展剖析 上节将Phoneword应用程序扩展到包含第二个屏幕,该屏幕可以跟踪应用程序的拨打历史 Navigation Xamarin.Form提供了一个内 ...

  5. CCNP路由实验之七 动态路由之BGP

     CCNP路由实验之七 动态路由之BGP 动态路由协议能够自己主动的发现远程网络,仅仅要网络拓扑结构发生了变化,路由器就会相互交换路由信息,不仅能够自己主动获知新添加的网络,还能够在当前网络连接失 ...

  6. latex 矩阵分块(block matrix)

    Lesson 12: Making Block Matrices in LATEX 按列分块: [AAb⋯An−1b] $$ \left[ \begin{array}{c|c|c|c} A & ...

  7. crossplatform---Nodejs in Visual Studio Code 03.学习Express

    1.开始 下载源码:https://github.com/sayar/NodeMVA Express组件:npm install express -g(全局安装) 2.ExpressRest 打开目录 ...

  8. WPF ListView 居中显示

    原文:WPF ListView 居中显示 今天遇到的问题: 方法1:设置GridViewColumn的ActualWidth <ListView > <ListView.View&g ...

  9. opengl实现直线扫描算法和区域填充算法

    总体介绍 1.   使用线性扫描算法画一条线,线性离散点 2.   利用区域填充算法画多边形区域,区域离散的点 开发环境VS2012+OpenGL 开发平台 Intel core i5,Intel H ...

  10. Shell脚本入门学习笔记

    1.shell操作系统和用户之间.负责解释命令行 2./etc/shells 记录登录系统有效支持shell 3./etc/passwd 最后,有人谁可以看到用户的默认shell 4.直接输入shel ...