Java 工具类总结(2): 再也不怕表单字符串处理 - String / StringBuilder / StringBuffer
2017-08-12 16:58
661 查看
String / StringBuilder / StringBuffer 是 Java 中字符串类;
本文从源码角度, 进行分析与总结:
1. String 常用的方法和注意点;
2. StringBuilder 和 StringBuffer 各自的特点;
3. 可变类和不可变类的实现原理
查看完整文档
![](https://oscdn.geek-share.com/Uploads/Images/Content/201708/7e21ef4d480b93829ba76709ec28a4e2)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201708/b9b0989a905c21bce64f3f97d4ccbea9)
Java 字符串是由 char 序列组成的, char 类型是一个采用 UTF-16 编码格式表示 Unicode 代码点的代码单元;
大多数字符使用一个代码点就可以表示, 而辅助字符需要两个代码点;
那么如何对具有两个代码点的字符串进行操作呢 ?
StringBuilder 是 JDK 1.5 引入的类;
当业务主要涉及字符串存储于访问的时候, 使用 String 类;
当业务主要涉及字符串 insert / update / delete 时候, 使用 StringBuilder ( 单线程) / StringBuffer (多线程)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201708/9aa92d7e3b5d76d7b53a19cdd3398eac)
Think in Java,
尚学堂 Java 300 集,
本文从源码角度, 进行分析与总结:
1. String 常用的方法和注意点;
2. StringBuilder 和 StringBuffer 各自的特点;
3. 可变类和不可变类的实现原理
1. String 类简要总结
1.1 String 源码分析
/** * The String class represents character strings. All * string literals in Java programs, such as {@code "abc"}, are * implemented as instances of this class. * String 类用于表述字符串字面量, 如: "abc" 就是 String 类的一个实例; * * Strings are constant; their values cannot be changed after they * are created. String buffers support mutable strings. * Because String objects are immutable they can be shared. For example: * <blockquote><pre> * String str = "abc"; * </pre></blockquote><p> * is equivalent to: * <blockquote><pre> * char data[] = {'a', 'b', 'c'}; * String str = new String(data); * </pre></blockquote><p> * Here are some more examples of how strings can be used: * <blockquote><pre> * System.out.println("abc"); * String cde = "cde"; * System.out.println("abc" + cde); * String c = "abc".substring(2,3); * String d = cde.substring(1, 2); * </pre></blockquote> * <p> * String 类是 Immutable 不可变的, String 实例能够被多个变量共享;(但是, 此处举的例子我没有看懂, 哪里能体现共享) * 我理解的共享: * String str1 = "Hello"; * String str2 = "Hello"; * 此时的 str1, str2 是指向同一个字符串存储地址的, 即 str1 == str2 为 true; * * The class {@code String} includes methods for examining * individual characters of the sequence, for comparing strings, for * searching strings, for extracting substrings, and for creating a * copy of a string with all characters translated to uppercase or to * lowercase. Case mapping is based on the Unicode Standard version * specified by the {@link java.lang.Character Character} class. * <p> * String 包含常用的方法: 比较 / 查找 / 提取子串 / 创建新字符串(全部大写/小写) * * The Java language provides special support for the string * concatenation operator (+), and for conversion of * other objects to strings. String concatenation is implemented * through the {@code StringBuilder}(or {@code StringBuffer}) * class and its {@code append} method. * String conversions are implemented through the method * {@code toString}, defined by {@code Object} and * inherited by all classes in Java. For additional information on * string concatenation and conversion, see Gosling, Joy, and Steele, * <i>The Java Language Specification</i>. * * * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor * or method in this class will cause a {@link NullPointerException} to be * thrown. * 不要试图访问 String str = null, 被赋予 null 值得字符串变量, 会 cause NullPointerException 错误 * * <p>A {@code String} represents a string in the UTF-16 format * in which <em>supplementary characters</em> are represented by <em>surrogate * pairs</em> (see the section <a href="Character.html#unicode">Unicode * Character Representations</a> in the {@code Character} class for * more information). * Index values refer to {@code char} code units, so a supplementary * character uses two positions in a {@code String}. * <p>The {@code String} class provides methods for dealing with * Unicode code points (i.e., characters), in addition to those for * dealing with Unicode code units (i.e., {@code char} values). * * @author Lee Boynton * @author Arthur van Hoff * @author Martin Buchholz * @author Ulf Zibis * @see java.lang.Object#toString() * @see java.lang.StringBuffer * @see java.lang.StringBuilder * @see java.nio.charset.Charset * @since JDK1.0 */
查看完整文档
1.2 String 演示
// 1. 字符串就是多个 Unicode 字符序列 String str = "Java\u2122"; System.out.println(str); // 2. used frequently methods String str2 = str.substring(0, 1); // s String str3 = str.substring(str.length()-1, str.length()); // /u2122 // 3. String is immutable class String str4 = str + "Hello"; String str5 = "Java\u2122Hello"; System.out.println(str4 == str5); // false String str8 = "hel"; char[] chs = {'h', 'e', 'l'}; String str9 = new String(chs); System.out.println(str8 == str9); // false //5. "" 和 null String str6 = ""; //str6 是 String 对象, 长度为 0, 值为 空 String str7 = null; // str7 只是 null 对象, 表示还没有被初始化 // 请不要试图使用 str7 进行操作 !!!
1.3 常用方法
1.4 关于 Java 采用 UTF-16 编码的问题
留下问题: (关于 Java 采用 UTF-16 编码的问题)Java 字符串是由 char 序列组成的, char 类型是一个采用 UTF-16 编码格式表示 Unicode 代码点的代码单元;
大多数字符使用一个代码点就可以表示, 而辅助字符需要两个代码点;
那么如何对具有两个代码点的字符串进行操作呢 ?
2. 从源码分析 StringBuilder / StringBuffer
总结: StringBuffer 和 StringBuilder 都是可变类;StringBuilder 是 JDK 1.5 引入的类;
当业务主要涉及字符串存储于访问的时候, 使用 String 类;
当业务主要涉及字符串 insert / update / delete 时候, 使用 StringBuilder ( 单线程) / StringBuffer (多线程)
2.1 继承关系
2.2 分析 StringBuilder 源码
StringBuilder 和 StringBuffer 所有方法都相同, 只是在线程安全和效率上有所区别, 因此, 我只演示 StringBuilder 的部分源码/** * A mutable sequence of characters. This class provides an API compatible * with {@code StringBuffer}, but with no guarantee of synchronization. * This class is designed for use as a drop-in replacement for * {@code StringBuffer} in places where the string buffer was being * used by a single thread (as is generally the case). Where possible, * it is recommended that this class be used in preference to * {@code StringBuffer} as it will be faster under most implementations. * * StringBuilder 是可变的字符序列, 它提供的类方法和 StringBuilder 完全相同, 但是它是非线程安全的 !!! * StringBuilder 类设计的初衷是, 希望在单线程(不要求线程安全)情境下, 替代 StringBuffer 类, 尽可能的 * 提高系统的运行效率; * * <p>The principal operations on a {@code StringBuilder} are the * {@code append} and {@code insert} methods, which are * overloaded so as to accept data of any type. Each effectively * converts a given datum to a string and then appends o ba44 r inserts the * characters of that string to the string builder. * StringBuilder 类中主要的方法包括: append() / insert() 方法; * * The {@code append} method always adds these characters at the end * of the builder; the {@code insert} method adds the characters at * a specified point. * <p> * append() 方法: 从末尾增加新字符串 * insert() 方法: 在指定索引位置增加字符串 * * For example, if {@code z} refers to a string builder object * whose current contents are "{@code start}", then * the method call {@code z.append("le")} would cause the string * builder to contain "{@code startle}", whereas * {@code z.insert(4, "le")} would alter the string builder to * contain "{@code starlet}". * * In general, if sb refers to an instance of a {@code StringBuilder}, * then {@code sb.append(x)} has the same effect as * {@code sb.insert(sb.length(), x)}. * * Every string builder has a capacity(容量, 这里指的是存储字符串的空间). As long as the length of the * character sequence contained in the string builder does not exceed * the capacity, it is not necessary to allocate a new internal * buffer. If the internal buffer overflows, it is automatically made larger. * 这里主要说明了 StringBuilder 类是动态调整存储空间的, 如果存储空间不足的话, 会自动增加存储空间; * 在父类 AbstractStringBuilder 中, ensureCapacityInternal() 方法就是用来确保存储空间问题; * (当然, StringBuffer 也具有相同的功能实现) * * <p>Instances of {@code StringBuilder} are not safe for * use by multiple threads. If such synchronization is required then it is * recommended that {@link java.lang.StringBuffer} be used. * * <p>Unless otherwise noted, passing a {@code null} argument to a constructor * or method in this class will cause a {@link NullPointerException} to be * thrown. * * @author Michael McCloskey * @see java.lang.StringBuffer * @see java.lang.String * @since 1.5 */ public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence { /** * Constructs a string builder with no characters in it and an * initial capacity of 16 characters. */ public StringBuilder() { super(16); // initial capacity: 16 个字符 } /** * Constructs a string builder with no characters in it and an * initial capacity specified by the {@code capacity} argument. * * @param capacity the initial capacity. * @throws NegativeArraySizeException if the {@code capacity} * argument is less than {@code 0}. */ public StringBuilder(int capacity) { super(capacity); } /** * Constructs a string builder initialized to the contents of the * specified string. The initial capacity of the string builder is * {@code 16} plus the length of the string argument. * * @param str the initial contents of the buffer. */ public StringBuilder(String str) { super(str.length() + 16); // 如果有 String 实参, 此时的容量是 str.length() + 16 个字符大小 append(str); } // append() 方法 // delete() 方法 // deleteCharAt() 方法 // replace() 方法 // insert() 方法 // indexOf() 方法 // reverse() 方法 }
2.3 解释可变类 和 不可变类的实现
那为什么, StringBuilder / StringBuffer 是可变的, 而 String 就不是可变的呢? 接下里, 就从源码上来分析:// from AbstractStringBuilder.java // AbstractStringBuilder 是 StringBuilder 和 StringBuffer 共同的父类 abstract class AbstractStringBuilder implements Appendable, CharSequence { /** * The value is used for character storage. */ char[] value; // 原来 StringBuffer 和 StringBuilder 都是通过 char[] value 进行存值嗒 // 最重要的是, 不是 final 修饰的哦, 当然可以改变 /** * The count is the number of characters used. */ int count; } // from String.java public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[]; // final 修饰, 这就是不可变的原因 }
3. 参考
Core Java Volumn I , Chapter 3.6Think in Java,
尚学堂 Java 300 集,
相关文章推荐
- Java——String和StringBuffer/StringBuilder字符串的常用方法
- Java探索之旅(10)——数组线性表ArrayList和字符串生成器StringBuffer/StringBuilder
- JAVA笔记系列:字符串操作——string stringbuilder stringbuffer
- 8.2-全栈Java笔记:字符串相关类(String/StringBuilder /StringBuffer)
- day7 常用类字符串处理类--String、StringBuffer、StringBuilder 自动装箱、拆箱 Object类 Java 的异常处理机制
- Java核心类库——String StringBuffer StringBuilder
- JAVA String StringBuffer Stringbuilder
- java.sql.Exception:setString 只能处理少于 32766 个字符的字符串
- 使用java.lang.String和java.lang.BufferString操作字符串
- Java基础知识-String StringBuffer StringBuilder比较
- 字符串工具类 StringUtil.java
- java字符串日期处理工具类
- CoreJava学习1——字符串处理(String和StringBuilder)&正则式
- 黑马程序员_毕向东Java基础_集合(1)String&StringBuffer&StringBuilder&基本数据类型包装类
- java中字符串编码的转换以及乱码后的处理总结
- 黑马程序员_Java学习日记_JAVA中API中对象String和StringBuffer/StringBuilder
- C/C++字符串处理盘点:Char*/String/StringBuilder/TextPool/Rope
- 用StringBuffer/StringBuilder对字符串进行拼接
- 居然还有人对字符串拼接操作时StringBuilder/StringBuffer取代“+”有疑问
- [C++]仿java.lang.String的字符串工具类[原]