My Blog

StringClass

记录 String 和 StringBuilder

学习笔记,仅供参考

参考B站Mirco_Frank - java 进阶 | 官方文档英文版


💬 String class

练习 String class

静态方法

  • String copyValueOf(char[] data, int offset, int count);   // 复制字符数组的内容,生成字符串并将其返回。其中 offset 为起始偏移量,count 为所复制字符的个数

  • String format(String format, Object... args);   // 格式化输出,类似 C 语言的 printf()

  • String join(CharSequence delimiter, CharSequence ...element);   // 拼接所给的子字符串,且用所给的 delimiter 连接, 返回拼接后的字符串

例:String message = String.join(".", "www", "google", "com"); 返回的字符串为 message = "www.google.com"

  • ★ String valueOf(int i);   // 将整型值转为一个字符串并返回;其他类型同理

方法

  • ★ int length();   // 返回字符串的长度

  • boolean isEmpty();   // 检验字符串是否为空, 是空串返回true, 否则返回false

  • char charAt(int index);   // 返回index处的字符,index范围从0到length-1

  • int codePointAt(int index);   // 返回index处字符的ASCII码

  • int codePointBefore(int index);   // 返回index前一字符的ASCII码

  • int codePointCount(int beginIndex, int endIndex);   // 返回从beginIndex后到endIndex的字符数

  • void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin);   // 从源字符串的srcBegin下标开始复制(srcEnd - srcBegin)个字符到目标数组,并且是从目标数组的dstBegin下标开始。【注:若复制的字符数超过数组剩余空间的长度则会报错】

  • byte[] getBytes();byte[] getBytes(String charsetName);   // 将对象序列化,并将其存储到新的数组中。其中 charsetName 有:”UTF-8”, “GBK”, “ISO-8859-1”等。

补充:序列化是将对象转化为二进制内容,本质为 byte[] 数组。作用就是用byte[] 数组来进行网络传输,即实现了 Java 对象的传输。同理,反序列化就是接收端还原为 Java 对象。

  • ★ boolean equals(Object anObject);   // 判断该对象是否与所给对象相同,相同为true,不同为false。

  • boolean equalsIgnoreCase(String otherString);   // 判断该字符串是否与所给字符串相同,且忽略大小写。

  • boolean contentEquals(StringBuffer sb);   // 将字符串与所给的StringBuffer比较

补充:String 与 StringBuffer, String为final类,一旦给定无法修改,修改也是重建, 而StringBuffer则可修改,不用再重新创建

  • ★ int compareTo(String otherString);
    从左到右比较两字符串,当出现不同时,返回该字符串与所给字符串不同处两字符ASCII的差值。完全相同时,返回整数0。

  • int compareToIgnoreCase(String otherString);   // 与 compareTo(); 方法类似,只是忽略大小写。

  • boolean regionMatches(boolean ignoreCase, int toofset, String otherString, int ooffset, int len);   // 比较该字符串的子段与所给的子段是否相同,相同返回true。

参数

ignoreCase – 为true,则比较字符时忽略大小写

toffset – 该字符串的起始偏移量

otherString – 所给的字符串

ooffset – 所给字符串的起始偏移量

len – 索要比较的字符数

  • boolean startsWith(String prefix, int toffset);   // 检验字符串是否以所给的前缀开始,toffset作位起始偏移量。

  • boolean endWith(String suffix);   // 检验字符串是否以所给的后缀结束。

  • int hashCode();   // 返回字符串的哈希码。

补充

hashcode 一种编码方式,任意长度的输入 –>[散列算法] –> 固定长度的输出(即哈希码)。

Java 中,对象相同,哈希码相同;哈希码相同,对象不一定相同。对象的物理地址先转化为整数,再通过 Hash 函数(一系列算法)得到 Hash 值,将这些值存放在表格中就构成了 Hash 表,对表的位置进行编码就得到了 Hash 码。

意义:提高搜索的速度。只需从某个 Hash 码下查找所要对象,不需遍历所有对象。

不恰当的例子:好比各地行政区的划分码。全国各地的地形地势(物理地址)经过划分规则(算法)使每块地都有所属的地区名(Hash值),如XX省XX市,再将这些地区名排列并放到表格中(Hash表),最后按表编码得到各地的行政区划分码(Hash码)。

参考此篇博客

  • int indexOf();   // 返回所给字符在该字符串的下标, 不存在则返回-1。

四种方法重载形式

int indexOf(int ch); (ch: ‘a’ or 97)

int indexOf(int ch, int fromIndex);

int indexOf(String str); (str: “a”)

int indexOf(String str, int fromIndex);   // fromIndex: 只从字符串的该下标开始从左到右查找。

  • int lastIndexOf(String str, int fromIndex);   // 形式与 int indexOf(); 类似,只是从右到左查找。

  • ★ String substring(int beginIndex, int endIndex);   // 获取该字符串的字串,从beginIndex 后开始,截取 (endIndex - beginIndex) 个字符。

  • CharSequence subSequence(int beginIndex, int endIndex);
    返回一个新的字符序列,与 substring(); 类似。

  • ★ String replace(char oldChar, char newChar);   // 字符或字符序列替换,并返回替换后的字符串

  • String replaceAll(String regex, String replacement);   // 用所给的replacement替换该字符串中所有匹配所给正则表达式的子字符串,成功返回替换的字符串,失败则返回原字符串

  • String replaceFrist(String regex, String replacdement);   // 同 replacAll(); 但只替换字符串中第一个满足正则的子串

  • boolean matches(String regex);   // 检测该字符串是否匹配所给的正则表达式

  • boolean contains(CharSequence cs);   // 检测该字符串是否包含所给的字符或字符序列

  • ★ String concat(String str);   // 将所给的字符串拼接到该字符串后面,并返回新的对象

  • ★ String[] split(String regex, int limit);   // 根据所给的正则表达式来切割该字符串,limit 指切割的份数,返回字符串数组

    for (String retval : str.split(regex, limit)){
    // 用for(** : **)来完成数组的元素接受,并进行操作
    System.out.println(retval); 
    }
    
    // 注:. $ | * 等转义字符必须用\\修饰才能使用
    // 注:多种分隔符,可用 | 来连接,如 "and|or"
    
  • String toLowerCase(); String toUpperCase();   // 将该字符串转为小写/大写

  • char[] toCharArray();   // 将该字符串转换为字符数组

  • ★ String trim();   // 返回删除该字符串的首尾空白符的字符串

  • ★ String intern();   // 复制该对象的内容给新的字符串并返回,并且将其存在常量池中

补充:

  1. 字符串一旦创建对象,就不可在被修改 (:让敏感数据变得安全些;:每次修改都要占据内存)

  2. 内存分为:堆、栈、常量池 (它是堆的一块特殊区域,用于存储字符串字面量)

  3. 字符串字面量(即“hello”),而字符串对象是由 new String(“hello”) 创建的;字符串字面量存在常量池中,对象存在堆中;相同的字符串字面量会指向同一地址,而内容相同的字符串对象则指向不同的地址

SCP-heap

除了 String 类之外,像 Integer、Double 等包装类也是一旦创建,不可改变的类

如何创建不可改变的类,要遵循下面几步:

  1. 类用 final 修饰,让其不再被继承

  2. 字段用 final 修饰,让字段只能被构造器实例

  3. 不要有 setter 方法

  4. 当有 setter 这种能修改属性的方法时,应该要返回一个新的实例

  5. 当类中有可变的对象时,要通过 cloneObject 作为中介,将参数交给 cloneObject,再让其交给真正的对象

具体解释参考how-to-create-an-immutable-class-in-java

值传递与引用传递

值传递(pass by value): 将变量的值传给所调用的方法

引用传递(pass by reference): 将对象所指向的地址传给所调用的方法,类似 C 语言的传指针,所以无论是外部对象还是方法的形参对象都会对所指向的地址的值有影响

若想让引用传递内外互不影响,那么就要让形参重新 new 个对象,如此就是两个不同的对象了

其实,在 Java 中并没有指针的概念,引用传递也是一种值传递,只不过它传的是内存地址的值而非内容值

详情参考CSDN SummerOfFoam 的解释 | java-pass-reference-pass-value


👁‍🗨 StringBuilder

为了解决字符串不可改变的问题,就有了 StringBuilder 类,它能在修改字符串而不产生新的对象,避免了创建多余的对象

构造器

  • StringBuilder()   // 创建空串并给 16 的初始容量

  • StringBuilder(String str)   // 创建字符串对象,内容为所给的 str

  • StringBuilder(int length)   // 创建空串,并指定容量为 length

方法

  • append(String s)   // 在该字符串后追加所给的 str

  • insert(int offset, String s)   // 在该字符串的第 offset 字母后插入所给的字符串

  • replace(int start, int end, String str)   // 从第 start+1 个字母开始到第 end 个字母的字串被所给串替换

  • delete(int start, int end)   // 从第 start+1 个字母开始到第 end 个字母的字串被删除

  • capacity()   // 返回该 Builder 的当前容量,新建时空串默认为 16,非空串则为 16+所给串的长度;当追加后的长度超出初始值时,就会以 (oldcapacity * 2) + 2 来自动扩容

  • ensureCapacity(int minimumCapacity)   // 确保当前容量不少于指定的最小容量,若少则自动扩容,不少则不变

  • trimToSize()   // 将当前容量缩减到字符串的大小

  • length()   // 返回字符串的大小

  • substring(int start, int end)   // 返回指定的字串

链式调用

当追加字符串时都要调用 append() 方法,但要是每次都写对象名就会显得有些多余,于是使用链式调用就会简化调用过程,让代码更加的简洁

StringBuilder sb = new StringBuilder();

// 追加字符串
sb.append("hello");
sb.append(" ");
sb.append("world");
sb.append("!");

/********************分割线*********************/

// 使用链式调用追加字符串
sb.append("hello").append(" ").append("world").append("!");