字符串和正则表达式
字符串原理:
概念:
字符串是有若干的字符组成的组成的一个有序序列,用一个String来表示一个字符串,字符串中的内容用双引号括起来,在双引号中,字符的数量不限制,可以是0个,可以是多个。
字符串的分类
不可变长字符串:
1.对应的类:String
2.特点:字符串本身不能发生改变,与指向字符串的引用无关
3.创建:直接使用“”,创建的是不可变长字符串
String str = "Hello World";
可变长字符串:
1.对应的类:StringBuffer/StringBuilder
2.特点:字符串本身可以发生变化,与指向可变长字符串的引用无关
3.创建可变长字符串:
StringBuffer stringBuffer = new StringBuffer("hello world");
字符串的内存分析:
字符串,是一个引用数据类型,但是字符串的引用,和之前在面向对象部分的引用有一点差别
差别:类的对象,是直接在堆上开辟的空间。字符串是在常量池中开辟的空间(常量池:是在方法区中的一个子空间)
/*
1.此时,“hello world”是在常量池里开辟的空间。str里存储的,实际是常量中的某一个内存的地址
2.当str = “30”的时候,其实,并不是修改了str指向的空间中的内容。因为常量池空间特性,一个空间一旦开辟完成了,里面的值是不允许修改的,此时,是在常量池中开辟的一块新的空间,存储了“30”,并在这个新空间的地址赋给str
3.字符串类型,之所以选择在常量池中进行空间的开辟,而不是在堆上、原因是需要使用享元原则
*/
String str1 = "hello world";
String str2 = "hello world";
System.out.println(str1 == str2);
/*
1.String是一个Java中用来描述字符串的类,里面是有构造方法的
2.通过String类提供的构造方法,实例化的字符串的对象,在堆上开辟的空间。在堆空间中有一个内部维护的属性,指向了常量池中的某一块空间
*/
String str = new String("hello world");
String str2 = new String("hello world");
System.out.println(str == str2);
System.out.println(str.equals(str2));
字符串拼接的内存分析:
1.直接使用两个字符串字面量进行拼接
1.1其实就是直接将两个由双引号直接括起来的字符串进行拼接。例:String str = “hello” + “world”;
1.2这里,直接在常量池中进行空间的操作,将常量池中拼接之后的结果,地址给str进行赋值
2.使用一个字符串变量和其他的进行拼接
2.1这里的拼接不是在常量池中直接完成的
2.2.在这个拼接的过程中,隐式的实例化了一个String类的对象,在堆上开辟了空间。堆上空间内部维护了一个指向常量池中拼接结果的一个属性。这个堆上的空间地址给左侧的引用进行了赋值
字符串的常用方法:
构造方法:
String()
String(str)
String(char[] newchar)
String(char[] array,int offset,int count)--通过一个字符数组实例化一个字符串,将字符数组中的指定范围的字符拼接到一起
String(byte[] array)--通过一个字节数组实例化一个字符串
String(byte[] array,int offset,int count)--通过一个字节数组实例化一个字符串
字符串的非静态方法:
返回值 | 方法名 | 方法描述 |
---|---|---|
boolean | isEmpty() | 判断一个字符串是否是空串 |
String | concat(String str) | 字符串的拼接,将一个字符串与另一个字符串拼接 |
char[] | toCharArray(String str) | 将字符串转成字符数组 |
String | subString(int begin,int end) | 字符串的截取,开始于begin,结束于end,(包含开头,不含结尾) |
String | replace(char old,char new) | 替换 |
char | charAt(int index) | 获取指定位置的字符串 |
byte[] | getBytes(String str) | 将字符串转成字节数组 |
int | indexOf(char c) | 获取某一字符在一个字符串中的位置 |
int | lastIndexOf(char c) | 获取某一字符在数组中最后一次出现的下标 |
String | toUpperCase() | 将字符串转成大写 |
String | toLowerCase() | 将字符串转成小写 |
boolean | contains(String str) | 判断一个字符串中是否包含另外的一个字符串 |
String | trim() | 去除了一个字符串前后的空格 |
boolean | equals(String str) | 判断两个字符串的内容是否相同 |
int | compareTo(String str) | 对两个字符串进行比较大小 |
boolean | startsWIth(String str) | 判断字符串是否另一个字符串开头 |
StringBuffer与StringBuilder:
概念:
StringBuffer和StringBuilder不是字符串类,使用来操作字符串的类,在类中维护了一个字符串的属性,这些字符串的操作类的方法,可以直接修改这个属性的值,对于使用方来讲,可以不去通过返回值获取操作的的结果
原理:
在StringBuffer和StringBuilder的类中,维护了一个字符数组,这些类中的所有操作方法,都是对这个字符数组进行的操作
常用方法:
返回值 | 常用方法 | 方法描述 |
---|---|---|
构造方法() | 空字符串 | |
构造方法(String str) | 指定字符串 | |
StringBuffer/StringBuilder | append | 拼接到结尾 |
StringBuffer/StringBuilder | insert(int offset,String str) | 插入到指定位置 |
StringBuffer/StringBuilder | delete(int start,int end) | 删除字符串指定位置的字符 |
StringBuilder/StringBuilder | replace(int start,int end,String str) | 替换,将字符串的中指定范围的字符串转成str |
void | setCharAt(int index,char c) | 将指定位置的字符替换成指定的字符 |
StringBuffer/StringBuilder | reverse() | 将一个字符串前后翻转 |
String | toString() | 返回一个正在操作的字符串 |
区别:
StringBuffer和StringBuilder从功能来讲是一模一样的,但是他们二者还有略微的区别
1.StringBuffer是线程安全地
2.StringBuilder是线程不安全的
使用场景:
当频繁使用字符串时,使用StringBuilder/StringBuffer,效率更高
正则表达式:
实现相同的功能,用String,StringBuffer,StringBuilder可以实现,用正则表达式也可以实现
正则表达式中的元字符:
^:匹配一个字符串的开头,可以不写
$:匹配一个字符串的结尾,可以不写
[]:匹配一个字符
[abc]:表示这一位的字符可以是a,可以是b,也可以是c
[a-z]:表示这一位的字符,可以是[a-z]范围内的任意字符
[a-zABC]:表示这一位的字符,可以是[a-z]范围内的任意字符,或者A,或者B,或者C
[a-zA-Z]:表示这一位的字符,可以是[a-z]范围内的任意字母,可以是大写也可以是小写
[^abc]:表示这一位的字符,可以是除abc之外的任意字符
[^a-z[hk]]:表示这一位的字符不能是任意的小写字母,但是hk除外
:转义字符,但是在java的正则表达式中,我们常常使用\
\d:匹配所有的数字
\D:匹配所有的非数字
\w:匹配所有的单词字符,等同于[a-zA-Z0-9]
\W:匹配所有的非单词字符
. : 通配符,可以匹配任意一个字符
+:前面的一位或者一组字符,出现了一次或者多次
?:前面的一位或者一组字符,连续出现了一次或零次
*:前面的一位或者一组字符,连续出现了任意次0
{}:对前面的一位或者一组字符出现次数的精确匹配
{m}:表示前面的一位或者一组字符连续出现了m次
{m,}:表示前面的一位或者一组字符连续出现了至少m次
{m,n}:表示前面的一位或者一组字符连续出现了至少m次,至少n次
|:作用于整体或者一个分组,表示匹配的内容,可以是任意的部分,
例:abc|123|opq:表示整体的部分可以是abc,也可以是123,也可以是opq、
():分组,将某些连续的字符视为一个整体对待
String类中常用的方法:
1.字符串的匹配:matches()
2.字符串的切割:split()
3.字符串的替换:replace()