String类和可变字符串类详解

来源:拉勾教育Java就业集训营

String类的概念

  • java.lang.String类用于描述字符串,Java程序中所有的字符串字面值都可以使用该类的对象加以描 述,如:"abc"。

  • 该类由final关键字修饰,表示该类不能被继承。

  • 从jdk1.9开始该类的底层不使用char[]来存储数据,而是改成 byte[]加上编码标记,从而节约了一 些空间

  • 该类描述的字符串内容是个常量不可更改,因此可以被共享使用。

  • 如: String str1 = “abc”; - 其中"abc"这个字符串是个常量不可改变。 str1 = “123”; - 将“123”字符串的地址赋值给变量str1。 - 改变str1的指向并没有改变指向的内容 ,"abc"如果没有被引用,会被垃圾回收机制回收


    01 String类型引用的指向改变.png
 public static void main(String[] args) {        
        String s1="abc";        
        String s2="abc";        
        System.out.println(s1==s2); //true 比较地址 abc存在常量池 
}

常量池的概念

由于String类型描述的字符串内容是常量不可改变,因此Java虚拟机将首次出现的字符串放入常量 池中,若后续代码中出现了相同字符串内容则直接使用池中已有的字符串对象而无需申请内存及创建对 象,从而提高了性能。

常用的构造方法

方法声明 功能介绍
String() 使用无参方式构造对象得到空字符序列 ,“” 表示空字符串
String(byte[] bytes, int offset, int length) 使用bytes数组中下标从offset位置开始的length个字节来 构造对象
String(byte[] bytes) 使用bytes数组中的所有内容构造对象
String(char[] value, int offset, int count) 使用value数组中下标从offset位置开始的count个字符来构 造对象
String(char[] value) 使用value数组中的所有内容构造对象
String(String original) 根据参数指定的字符串内容来构造对象,新创建对象为参数对象的副本
public static void main(String[] args) {
 //下面代码会创建几个对象,分别存放在哪里
 String s1="abc";  // 1个对象 存在常量池
 String s2=new String("abc");  //2个对象  "abc"在常量池  new的对象在堆区(堆区存abc的副本) s2指向堆区
 String s3="hello";
 String s4="hello";
 String s5=new String("hello");
 String s6=new String("hello");
 System.out.println(s3==s4);         //true
 System.out.println(s3.equals(s4));  //true
 System.out.println(s5==s6);         //false
 System.out.println(s5.equals(s6));  //true
 System.out.println(s3==s5);         //false
 System.out.println(s3.equals(s5));  //true

 //常量由优化机制,变量没有
 String a1="abcd";
 String a2="ab"+"cd";       // 常量优化机制   "abcd"
 System.out.println(a1==a2);//比较地址 true
 String a3="ab";
 String a4=a3+"cd";          //没有优化机制
 System.out.println(a3==a4);//比较地址 false
}

常用的成员方法

方法声明 功能介绍
String toString() 返回字符串本身,重写Object toString()方法
byte[] getBytes() 将当前字符串内容转换为byte数组并返回,先将字符串拆分为字符,再将字符转byte
char[] toCharArray() 用于将当前字符串内容转换为char数组并返回
char charAt(int index) 方法charAt用于返回字符串指定位置的字符。
int length() 返回字符串字符序列的长度
boolean isEmpty() 判断字符串是否为空
int compareTo(String anotherString) 用于比较调用对象和参数对象的大小关系
int compareToIgnoreCase(String str) 不考虑大小写,也就是'a'和'A'是相等的关系
String concat(String str) 用于实现字符串的拼接
boolean contains(CharSequence s) 用于判断当前字符串是否包含参数指定的内容,String实现类CharSequence接口
String toLowerCase() 返回字符串的小写形式 //常量 转换后不会改变原值
String toUpperCase() 返回字符串的大写形式
String trim() 返回去掉前导和后继空白的字符串
boolean startsWith(String prefix) 判断字符串是否以参数字符串开头
boolean startsWith(String prefix, int toffset) 从指定位置开始是否以参数字符串开头
boolean endsWith(String suffix) 判断字符串是否以参数字符串结尾
boolean equals(Object anObject) 用于比较字符串内容是否相等并返回
int hashCode() 获取调用对象的哈希码值
boolean equalsIgnoreCase(String anotherString) 用于比较字符串内容是否相等并返回,不考虑大小写, 如:'A'和'a'是相等
int indexOf(int ch) 用于返回当前字符串中参数ch指定的字符第一次出现的 下标
int indexOf(int ch, int fromIndex) 用于从fromIndex位置开始查找ch指定的字符
int indexOf(String str) 在字符串中检索str返回其第一次出现的位置,若找不到 返回-1,正向查找
int indexOf(String str, int fromIndex) 表示从字符串的fromIndex位置开始检索str第一次出现 的位置
int lastIndexOf(int ch) 用于返回参数ch指定的字符最后一次出现的下标
int lastIndexOf(int ch, int fromIndex) 用于从fromIndex位置开始查找ch指定字符出现的下标
int lastIndexOf(String str) 返回str指定字符串最后一次出现的下标 ,反向查找
int lastIndexOf(String str, int fromIndex) 用于从fromIndex位置开始反向搜索的第一次出现的下 标。
String substring(int beginIndex, int endIndex) 返回字符串中从下标beginIndex(包括)开始到 endIndex(不包括)结束的子字符串
String substring(int beginIndex) 返回字符串中从下标beginIndex(包括)开始到字符串结尾 的子字符串

正则表达式的概念

正则表达式本质就是一个“规则字符串”,可以用于对字符串数据的格式进行验证,以及匹配、查 找、替换等操作。该字符串通常使用^运算符作为开头标志,使用$运算符作为结尾标志,当然也可以省 略。

正则表达式的规则

正则表达式 说明
[abc] 可以出现a、b、c中任意一个字符
[^abc] 可以出现任何字符,除了a、b、c的任意字符
[a-z] 可以出现a、b、c、……、z中的任意一个字符
[a-zA-Z0-9] 可以出现az、AZ、0~9中任意一个字符
. 任意一个字符(通常不包含换行符)
\d 任意一个数字字符,相当于[0-9]
\D 任意一个非数字字符
\s 空白字符,相当于[\t\n\x0B\f\r]
\S 非空白字符
\w 任意一个单词字符,相当于[a-zA-Z_0-9]
\W 任意一个非单词字符
X? 表示X可以出现一次或一次也没有,也就是0 ~ 1次
X* 表示X可以出现零次或多次,也就是0 ~ n次
X+ 表示X可以出现一次或多次,也就是1 ~ n次
X{n} 表示X可以出现恰好 n 次
X{n,} 表示X可以出现至少 n 次,也就是>=n次
X{n,m} 表示X可以出现至少 n 次,但是不超过 m 次,也就是>=n并且<=m次

用 () 进行分组,无实际意义

正则表达式相关的方法

方法名称 方法说明
boolean matches(String regex) 判断当前正在调用的字符串是否匹配参数指定的正则表达式规 则
String[] split(String regex) 参数regex为正则表达式,以regex所表示的字符串为分隔 符,将字符串拆分成字符串数组
String replace(char oldChar, char newChar) 使用参数newChar替换此字符串中出现的所有参数 oldChar
String replaceFirst(String regex, String replacement) 替换此字符串匹配给定的正则表达式的第一个子字符串
String replaceAll(String regex, String replacement) 将字符串中匹配正则表达式regex的字符串替换成 replacement

可变字符串类

基本概念
  • 由于String类描述的字符串内容是个常量不可改变,当需要在Java代码中描述大量类似的字符串 时,只能单独申请和存储,此时会造成内存空间的浪费。

  • 为了解决上述问题,可以使用java.lang.StringBuilder类和java.lang.StringBuffer类来描述字符序 列可以改变的字符串,如:"ab"。

  • StringBuffer类是从jdk1.0开始存在,属于线程安全的类,因此效率比较低。

  • StringBuilder类是从jdk1.5开始存在,属于非线程安全的类,效率比较高。

StringBuilder类常用的构造方法
方法声明 功能介绍
StringBuilder() 使用无参方式构造对象,容量为16
StringBuilder(int capacity) 根据参数指定的容量来构造对象,容量为参数指定大小
StringBuilder(String str) 根据参数指定的字符串来构造对象,容量为:16+字符串长度
StringBuilder类常用的成员方法
方法声明 功能介绍
int capacity() 用于返回调用对象的容量
int length() 用于返回字符串的长度,也就是字符的个数
StringBuilder insert(int offset, String str) 插入字符串并返回调用对象的引用,就是自己
StringBuilder append(String str) 追加字符串
StringBuilder deleteCharAt(int index) 将当前字符串中下标为index位置的单个字符 删除
StringBuilder delete(int start,int end) 删除字符串
StringBuilder replace(int start,int end, String str) 替换字符串
StringBuilder reverse() 字符串反转
StringBuilder setCharAt(int index,char char) 修改下标为index的字符为char

注意 作为参数传递的话,方法内部String不会改变其值,StringBuffer和StringBuilder会改变其值

返回值的设计
  • StringBuilder的很多方法的返回值均为StringBuilder类型。这些方法的返回语句均为:return this

  • 由此可见,这些方法在对StringBuilder所封装的字符序列进行改变后又返回了该对象的引用。基 于这样设计的目的在于可以连续调用

扩容算法源码分析

当字符串的长度超过了字符串对象的初始容量时,该字符串对象会自动扩容,默认扩容算法是:原始容量 *2+2

底层采用byte数组来存放所有的字符内容

考点
  • 考点一:既然StringBuilder类的对象本身可以修改,那么为什么成员方法还有返回值呢? 解析:为了连续调用 sb3.reverse().append("1").append("2").insert(0, "3").delete(0, 1).reverse();

  • 考点二:如何实现StringBuilder类型和String类型之间的转换呢? String str3 = sb3.toString(); StringBuilder sb5 = new StringBuilder(str3);

  • 考点三:String、StringBuilder、StringBuffer之间效率谁高?排列如何? String < StringBuffer < StringBuilder

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容