String

  • 无参数构造函数
  1. /**
  2. * 底层存储字符串的目标字节数组,
  3. * Jdk 8 之前都是字符数组 private final char[] value;
  4. */
  5. @Stable
  6. private final byte[] value;
  7. /**
  8. * 编码底层字节数组的字符集,支持 LATIN1、UTF16
  9. */
  10. private final byte coder;
  11. /**
  12. * 字符串的哈希码值,默认为 0
  13. */
  14. private int hash; // Default to 0
  15. /**
  16. * 创建一个空字符串
  17. * created by ZXD at 18 Nov 2018 T 11:17:48
  18. */
  19. public String() {
  20. this.value = "".value;
  21. this.coder = "".coder;
  22. }
  • 基于字节数组创建字符串
  1. public String(byte[] bytes) {
  2. this(bytes, 0, bytes.length);
  3. }
  4. public String(byte bytes[], int offset, int length) {
  5. checkBoundsOffCount(offset, length, bytes.length);
  6. // 对目标字节数组进行编码
  7. StringCoding.Result ret = StringCoding.decode(bytes, offset, length);
  8. // 获取编码后的字节数组
  9. this.value = ret.value;
  10. // 获取编码后的字符集
  11. this.coder = ret.coder;
  12. }
  13. public String(byte bytes[], Charset charset) {
  14. this(bytes, 0, bytes.length, charset);
  15. }
  16. public String(byte bytes[], int offset, int length, Charset charset) {
  17. // 防御式编程,null 校验
  18. if (charset == null)
  19. throw new NullPointerException("charset");
  20. checkBoundsOffCount(offset, length, bytes.length);
  21. // 根据指定的字符集对字节数组进行编码
  22. StringCoding.Result ret =
  23. StringCoding.decode(charset, bytes, offset, length);
  24. this.value = ret.value;
  25. this.coder = ret.coder;
  26. }
  27. public String(byte bytes[], String charsetName)
  28. throws UnsupportedEncodingException {
  29. this(bytes, 0, bytes.length, charsetName);
  30. }
  31. public String(byte bytes[], int offset, int length, String charsetName)
  32. throws UnsupportedEncodingException {
  33. if (charsetName == null)
  34. throw new NullPointerException("charsetName");
  35. checkBoundsOffCount(offset, length, bytes.length);
  36. // 根据指定的字符集对字节数组进行编码,编码名称错误时,抛出 UnsupportedEncodingException 异常
  37. StringCoding.Result ret =
  38. StringCoding.decode(charsetName, bytes, offset, length);
  39. this.value = ret.value;
  40. this.coder = ret.coder;
  41. }
  • 基于字符数组创建字符串
  1. public String(char value[]) {
  2. this(value, 0, value.length, null);
  3. }
  4. public String(char value[], int offset, int count) {
  5. this(value, offset, count, rangeCheck(value, offset, count));
  6. }
  7. private static Void rangeCheck(char[] value, int offset, int count) {
  8. // 字符串下标合法性校验
  9. checkBoundsOffCount(offset, count, value.length);
  10. return null;
  11. }
  12. String(char[] value, int off, int len, Void sig) {
  13. // 特殊场景优化处理
  14. if (len == 0) {
  15. this.value = "".value;
  16. this.coder = "".coder;
  17. return;
  18. }
  19. if (COMPACT_STRINGS) {
  20. // 如果启用压缩,则将字符数组压缩,字符集设置为 LATIN1
  21. byte[] val = StringUTF16.compress(value, off, len);
  22. if (val != null) {
  23. this.value = val;
  24. this.coder = LATIN1;
  25. return;
  26. }
  27. }
  28. // 字符数组不压缩时,字符集设置为 UTF16
  29. this.coder = UTF16;
  30. this.value = StringUTF16.toBytes(value, off, len);
  31. }
  • 字符串内容相等性比较
  1. public boolean equals(Object anObject) {
  2. // 地址相等则直接返回 true
  3. if (this == anObject) {
  4. return true;
  5. }
  6. // 形参对象为字符串
  7. if (anObject instanceof String) {
  8. String aString = (String)anObject;
  9. // 字符编码相同时才能做比较
  10. if (coder() == aString.coder()) {
  11. return isLatin1() ? StringLatin1.equals(value, aString.value)
  12. : StringUTF16.equals(value, aString.value);
  13. }
  14. }
  15. return false;
  16. }
  • 字符串的长度
  1. public int length() {
  2. return value.length >> coder();
  3. }
  4. byte coder() {
  5. return COMPACT_STRINGS ? coder : UTF16;
  6. }
  7. @Native static final byte LATIN1 = 0;
  8. @Native static final byte UTF16 = 1; // Unicode字符集的抽象码位映射为16位长的整数
  • 比较字符串内容并且不区分大小写
  1. public boolean equalsIgnoreCase(String anotherString) {
  2. return (this == anotherString) ? true
  3. : (anotherString != null) // 形参字符串不为 null
  4. && (anotherString.length() == length()) // 两个字符串长度一致
  5. && regionMatches(true, 0, anotherString, 0, length()); // 编码后的区域是否匹配
  6. }
  • 字符串拼接
  1. public String concat(String str) {
  2. int olen = str.length();
  3. if (olen == 0) {
  4. return this;
  5. }
  6. // 字符集相同时,直接通过数组拷贝进行拼接
  7. if (coder() == str.coder()) {
  8. byte[] val = this.value;
  9. byte[] oval = str.value;
  10. int len = val.length + oval.length;
  11. byte[] buf = Arrays.copyOf(val, len);
  12. System.arraycopy(oval, 0, buf, val.length, oval.length);
  13. return new String(buf, coder);
  14. }
  15. int len = length();
  16. // 使用 UTF16 编码计算目标字节数组长度,并将它们都拷贝进去。
  17. byte[] buf = StringUTF16.newBytesFor(len + olen);
  18. getBytes(buf, 0, UTF16);
  19. str.getBytes(buf, len, UTF16);
  20. return new String(buf, UTF16);
  21. }
  • 字符串截取
  1. public String substring(int beginIndex, int endIndex) {
  2. int length = length();
  3. // 索引合法性检测
  4. checkBoundsBeginEnd(beginIndex, endIndex, length);
  5. int subLen = endIndex - beginIndex;
  6. // 特殊场景优化处理,截取的子字符串就是目标字符串
  7. if (beginIndex == 0 && endIndex == length) {
  8. return this;
  9. }
  10. return isLatin1() ? StringLatin1.newString(value, beginIndex, subLen)
  11. : StringUTF16.newString(value, beginIndex, subLen);
  12. }
  13. /**
  14. * 起始索引和结束索引不在 0到 length()-1 范围内,则抛出 IndexOutOfBoundsException 异常
  15. * 结束索引大于起始索引,则抛出 IndexOutOfBoundsException 异常
  16. */
  17. static void checkBoundsBeginEnd(int begin, int end, int length) {
  18. if (begin < 0 || begin > end || end > length) {
  19. throw new StringIndexOutOfBoundsException(
  20. "begin " + begin + ", end " + end + ", length " + length);
  21. }
  22. }
  • 获取字符串中指定索引处的单个字符
  1. public char charAt(int index) {
  2. if (isLatin1()) {
  3. return StringLatin1.charAt(value, index);
  4. } else {
  5. return StringUTF16.charAt(value, index);
  6. }
  7. }
  8. StringLatin1#charAt
  9. public static char charAt(byte[] value, int index) {
  10. if (index < 0 || index >= value.length) {
  11. throw new StringIndexOutOfBoundsException(index);
  12. }
  13. return (char)(value[index] & 0xff);
  14. }
  • 目标字符串是否包含子字符串
  1. public boolean contains(CharSequence s) {
  2. return indexOf(s.toString()) >= 0;
  3. }
  • 字符串是否为空
  1. public boolean isEmpty() {
  2. return value.length == 0;
  3. }
  • 字符串替换
  1. public String replace(char oldChar, char newChar) {
  2. if (oldChar != newChar) {
  3. String ret = isLatin1() ? StringLatin1.replace(value, oldChar, newChar)
  4. : StringUTF16.replace(value, oldChar, newChar);
  5. if (ret != null) {
  6. return ret;
  7. }
  8. }
  9. return this;
  10. }
  11. public String replace(CharSequence target, CharSequence replacement) {
  12. // 需要查找的字符序列
  13. String tgtStr = target.toString();
  14. // 需要替换的字符序列
  15. String replStr = replacement.toString();
  16. // 如果要查找的字符序列没有在目标字符串中,则返回其本身
  17. int j = indexOf(tgtStr);
  18. if (j < 0) {
  19. return this;
  20. }
  21. // 查找字符序列的长度
  22. int tgtLen = tgtStr.length();
  23. int tgtLen1 = Math.max(tgtLen, 1);
  24. // 当期字符串的长度
  25. int thisLen = length();
  26. int newLenHint = thisLen - tgtLen + replStr.length();
  27. if (newLenHint < 0) {
  28. throw new OutOfMemoryError();
  29. }
  30. StringBuilder sb = new StringBuilder(newLenHint);
  31. int i = 0;
  32. // 在 StringBuilder 指定的索引处追加字符串,并重新获取要查找的子字符串索引进行循环替换。
  33. do {
  34. sb.append(this, i, j).append(replStr);
  35. i = j + tgtLen;
  36. } while (j < thisLen && (j = indexOf(tgtStr, j + tgtLen1)) > 0);
  37. return sb.append(this, i, thisLen).toString();
  38. }
  • 基于正则表达式替换字符串
  1. public String replaceAll(String regex, String replacement) {
  2. return Pattern.compile(regex).matcher(this).replaceAll(replacement);
  3. }
  • 基于正则表达式替换首次出现的字符串
  1. public String replaceFirst(String regex, String replacement) {
  2. return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
  3. }

String 部分源码分析的更多相关文章

  1. String 类源码分析

    String 源码分析 String 类代表字符序列,Java 中所有的字符串字面量都作为此类的实例. String 对象是不可变的,它们的值在创建之后就不能改变,因此 String 是线程安全的. ...

  2. python string.py 源码分析 三:maketrans

    l = map(chr, xrange(256)) #将ascii转为字符串 _idmap = str('').join(l) del l # Construct a translation stri ...

  3. String类源码分析(JDK1.7)

    以下学习根据JDK1.7String类源代码做注释 public final class String implements java.io.Serializable, Comparable<S ...

  4. python string.py 源码分析 二:capwords

    def capwords(s, sep=None): """capwords(s [,sep]) -> string Split the argument into ...

  5. String类源码分析

    1.String类注释说明 /** * The {@code String} class represents character strings. All * string literals in ...

  6. python string.py 源码分析 一

    # Some strings for ctype-style character classification c风格字符串 whitespace = ' \t\n\r\v\f' #空白字符 \t 制 ...

  7. 【源码分析】你必须知道的string.IsNullOrEmpty && string.IsNullOrWhiteSpace

    写在前面 之前自信撸码时踩了一次小坑,代码如下: private static void AppServer_NewMessageReceived(WebSocketSession session, ...

  8. Java源码分析:关于 HashMap 1.8 的重大更新(转载)

    http://blog.csdn.net/carson_ho/article/details/79373134 前言 HashMap 在 Java 和 Android 开发中非常常见 而HashMap ...

  9. [源码]String StringBuffer StringBudlider(2)StringBuffer StringBuilder源码分析

      纵骑横飞 章仕烜   昨天比较忙 今天把StringBuffer StringBulider的源码分析 献上   在讲 StringBuffer StringBuilder 之前 ,我们先看一下 ...

随机推荐

  1. java 实现傅立叶变换算法 及复数的运算

    最近项目需求,需要把python中的算法移植到java上,其中有一部分需要用到复数的运算和傅立叶变换算法,废话不多说 如下: package qrs; /** * 复数的运算 * */ public ...

  2. Spring-data-jpa n+1问题

    Spring-data-jpa的n+1问题 当我们使用JPA提供给我们的find方法时,如果查询出来的对象关联着另外10个对象,那么JPA将会发送1+10次查询(这个对象本身要查询一次,然后每个关联对 ...

  3. Delphi 字符串运算符

  4. 新建ext4分区及开机挂载

    1.查看新的20G硬盘是否已经挂在完毕. 2.使用fdisk命令创建主分区 3.再将分区设置完毕之后,查看磁盘分区是否创建完成. 2.使用mkfs.ext4命令将新创建的分区进行格式化为: 1)blo ...

  5. CentOS 7添加开机启动服务脚本

    一.添加开机自启服务 在CentOS 7中添加开机自启服务非常方便,只需要两条命令(以Jenkins为例): systemctl enable jenkins.service #设置jenkins服务 ...

  6. 转发(forward)和重定向(redirect)的区别?

    1)forward是容器中控制权的转向,是服务器请求资源,服务器直接访问目标地址的URL,把那个URL 的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所 ...

  7. 【NOIP2016提高A组集训第3场10.31】高维宇宙

    题解 分析 因为只有奇数和偶数配对才有可能得出质数, 暴力求出每一对\(a_i+a_j\)为质数,将其中的奇数想偶数连一条边. 二分图匹配,匈牙利算法. #include <cmath> ...

  8. 【leetcode】1221. Split a String in Balanced Strings

    题目如下: Balanced strings are those who have equal quantity of 'L' and 'R' characters. Given a balanced ...

  9. asp.net mvc 异步控制器

    参考:https://blog.csdn.net/niewq/article/details/20490707 https://www.cnblogs.com/visonme/p/5537190.ht ...

  10. Cassandra介绍

    Cassandra介绍 Apache Cassandra 是一个开源的.分布式.无中心.弹性可扩展.高可用.容错.一致性可调.面向列的数据库.它基于Amazon Dynamo的分布式设计 Cassan ...