------- android培训、java培训、期待与您交流! ----------
String
类代表字符串。Java 程序中的所有字符串字面值(如 "abc"
)都作为此类的实例实现。
字符串是常量;它们的值在创建之后不能更改。
它的构造函数很丰富,用的频率也很高。String()初始化一个新创建的
String
对象,使其表示一个空字符序列。String(byte[] bytes)通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的
String
。
String(byte[] bytes,Charset charset)通过使用指定的charset 解码指定的 byte 数组,构造一个新的
String
。
String(byte[] bytes, int offset, int length)通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的
String
。
bytes
- 要解码为字符的 byteoffset
- 要解码的第一个 byte 的索引length
- 要解码的 byte 数
String(char[] value)分配一个新的
String
,使其表示字符数组参数中当前包含的字符序列
String(StringBuffer buffer)分配一个新的字符串,它包含字符串缓冲区参数中当前包含的字符序列。
String(StringBuilder builder)
分配一个新的字符串,它包含字符串生成器参数中当前包含的字符序列。
字符串的常见方法:
获取:
获取字符串的长度:int getLength();获取指定位置上的字符:char charAt(int index);根据字符获取位置,如果此字符串中没有这样的字符,则返回-1
。:int indexOf(int c)
indexOf(int ch, int fromIndex)返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索。如果此字符串中没有这样的字符,则返回
-1
。
indexOf(String str)
indexOf(String str, int fromIndex)这两个方法的参数是一个字符串,作用和传入字符一样,没有这个字符串则返回-1
lastIndexOf(int ch)返回指定字符在此字符串中最后一次出现处的索引。没有这个字符串则返回-1。
判断:
startsWith(String prefix)测试此字符串是否以指定的前缀开始。
startsWith(String prefix, int toffset)测试此字符串从指定索引开始的子字符串是否以指定前缀开始。
isEmpty()当且仅当
length()
为 0 时返回 true。contains(CharSequence s)当且仅当此字符串包含指定的 char 值序列时,返回 true
endsWith(String suffix)测试此字符串是否以指定的后缀结束。
equals(Object anObject)将此字符串与指定的对象比较。
替换:
String replace(char oldChar, char newChar)返回一个新的字符串,它是通过用
newChar
替换此字符串中出现的所有oldChar
得到的。
如果替换的字符不存在那么返回的还是原字符串。
String replace(CharSequence target,CharSequence replacement)使用指定的字符串替换此字符串所有匹配字面值目标序列的子字符串。如果没有返回原字符串
切割:
subString(index);从指定位置开始到结尾,如果角标不存在则会发生角标越界异常;
subString(from,to);包含头不包含尾。
转换:
将字符串转换成大写或小写:
toUpperCase(); toLowerCase();
String trim(); 去除两端的空格
s1.compareTo(s2);对两个字符串进行自然顺序比较
如果参数字符串等于此字符串,则返回值 0
;如果此字符串按字典顺序小于字符串参数,则返回一个小于0
的值;
如果此字符串按字典顺序大于字符串参数,则返回一个大于 0
的值
这些是很常见的方法,因此这些方法都要熟练掌握!
这些是很常见的方法,因此这些方法都要熟练掌握!
自己依照老师的例子写的trim()方法:
字符串翻转练习:
StringBuffer类:
它是字符串缓冲区,是一个容器是线程安全的。特点是:长度是可变的,可以操作多个数据类型,最终通过字符串的方法编程字符串。
它的构造函数:
StringBuffer()造一个其中不带字符的字符串缓冲区,其初始容量为 16 个字符
StringBuffer(String str)构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容。
1,存储:
StringBuffer append():将指定的数据添加到已有数据的结尾处。
StringBuffer insert(index,数据)可以将数据插入到指定的位置。
2,删除:
StringBuffer delete(start,end)包含头不包含尾。可以清空缓冲区,delete(0,sb.length());
StringBuffer deleteCharAt(index);删除指定位置的char
3,获取:
char charAt(index);通过角标获取单个字符。
int indexOf(String str)通过给定字符串获取第一次出现的位置。
int lastIndexOf(String str);通过给定的字符串获取最后出现的位置。
int length();获取长度
String substring(start,end);获取某一部分的字符串,包含头不包含尾。
4,修改:
StringBuffer replace(start,end,String str)'
void setCharAt(index,char)
5,反转:
StringBuffer reverse();
6,getChars(start,end,char[],bigin);将某一段字符串添加到一个char数组,从这个数组的bigin角标开始插入。
StringBuilder 和StringBuffer作用一样只不过,StringBuilder线程不同步不安全,但是效率高,每次调用方法不用判断锁。
字符串常量池:
什么是常量池:常量池是指在编译期间就确定,并保存在字节码文件中的一些数据。
(它包括类,方法,借口等其中的常量,也包含字符串常量)
//下面举例说明常量池
*/
//1,下面创建了一些字符串常量
String s="ab";
String s1="ab";
String s2="a"+"b";
System.out.println(s==s1);//返回结果为true
System.out.println(s==s2);//返回结果为true
/* 那么为什么都是true呢,分析下原因;
如上面的操作创建一个字符串会在编译期间就会被解析成一个字符串常量,
并且保存在字符串常量池中。
第一步:String s="ab";在编译期间就被解析保存在字符串常量池中
第二步:String s1="ab";在编译期间也被解析成一个字符串常量,而常量池中有了"ab"
所以s1也是常量池中“ab”的一个引用
第三步:String s2="a"+"b";对于字符串“+”的连接,在编译期间JVM就会对"a"+"b"解析成连接
后的值也就是“ab”,所以s2也也是常量池中"ab"的一个引用
因此结果:它们的地址 都一样所以为true
*/
//2,下面讲下直接赋值和new出来的区别
String s="ab";
String s1=new String("ab");
String s2="a"+new String("b");
System.out.println(s==s1);//结果返回false
System.out.println(s==s2);//结果返回false
/*分析如下
第一步:String s="ab";它会在编译期间就被JVM解析并保存在字符串常量池中s为“ab”的引用
第二步:String s1=new String("ab");因为new String();出来的字符串不是常量,在编译期间它不会被确定
因此不会保存在常量池中,而在运行期间被解析,在堆内存中创建一个字符串实例,它有自己的新地址
第三步:String s2="a"+new String("b");上面说过,有+连接的地方在编译期间会被解析成一个连接后的字符串
但是在此例中+的后半部分并不能在编译期间被解析,因此它也是在运行时期创建一个新的实例,
有自己的地址
*/
//3,原语String的intern()方法的介绍
/*这里有一个知识点就是,常量池在会在运行时被虚拟机装载,并且可以扩充
而intern()方法就是扩充字符串常量池的一个方法;
当String 的实例s 调用intern()方法时会查看字符串常量池中是否有这个字符串常量,
如果有则返回这个字符串常量的引用,没有将会在字符串常量池中添加一个s的字符串常量;
并返回在常量池中的字符串引用,因此地址会变
*/
String s="ab";
String s1=new String("ab");
String s2=new String("ab");
//这里为什么都是false因为它们的地址都不同
System.out.println(s==s1);//返回false
System.out.println(s==s2);//返回false
System.out.println(s1==s2);//返回fase
//下面通过s1调用intern()方法
s1.intern();//注意这个方法的介绍,并没有将返回后的引用再次赋值给s1,只是调用了一下
s2=s2.intern();
System.out.println(s==s1);//返回false
System.out.println(s==s2);//返回true
/*
第一步:s1调用了intern()方法,查看常量池中是否存在“ab”,结果存在应该返回在字符串常量池中的引用
但在这一步中我们并没有把这个引用赋值给s1因此s1还是堆内存中的引用,因此地址不同返回false
第二步:s2调用了intern()方法,重复上一步的步骤,将常量池中的引用返回给了s2因此s2的引用指向了
字符串常量池中的地址,因此返回了true
通过这个例子也可以看到:在调用intern()方法时,并不是把在堆内存中的地址赋给了常量池中的地址
还有就是对于String s="ab";String s1="a";String s2=s1+"b";这个例子来说跟new String()那个例子类似,
不能在编译期间就确定,而是在运行时期赋予新的地址值
*/
正则表达式:
符合一定规则的表达式:是专门用于操作字符串的。用于简化对字符串的复杂操作。
在正则表达式中:反斜线是一对对出现的,因为反斜线是个转义字符在正则表示式中例如:\d 这个组合代表数字[0-9]但是在程序中如果直接这样写代表了
将d字母转义了,而\d是一个组合所以在程序中要将\转义就是\\d这样就代表了这个组合。
[]的含义应该是代表了一位:这里面可以写入这位里可以出现的数字字母符号等。()代表了一组用\1的形式代表了这一组的值。如果定义了多个组那么我们先看有几个(就证明有几个组,第二组用\2表示以此类推(当判断单词字符是否重复时可以用到组的概念)。{}表示前面的位要出现的次数。例如[0-9]{2}那就说明要匹配的这个字符串一共有两位,每位都是0-9的数字
为了简化书写:[0-9]可以用\d表示[^0-9]可以用\D表示。\w表示单词字符[a-zA-Z_0-9]。\W表示非单词字符。 .代表了这个位可以是任何单词字符。
X? 代表了:X,一次或一次也没有。X*代表了:X,零次或多次。X+代表了:X,一次或多次。X{N}代表了:X,恰好N次。X{N,}代表了N,至少N次
X{N,M}代表了X,至少N次,但不超过M次
匹配:String类中有个metches(regex);方法这里的参数是一个正则表达式;返回类型true or false如果匹配返回true如果不匹配返回false
String regex="[0-9]{3}";
String str="022";
System.out.println(str.matches(regex));这里会返回true因为str就是三位每位的数字都是0-9的范围之内。
匹配一个手机号码:第一位是1,第二位可以是3,5,8,后面9位可以是任何数字:
String str="13651391098";
String regex="[1][3,5,8]\\d{7}";
System.out.println(str.matches(regex));//此结果返回true
匹配一个手机号码:第一位是1,第二位可以是3,5,8,后面9位中可以是任何数字,但后面的五位是重复的:
String regex="[1][3,5,8]\\d{4}(\\d)\\1{4}";
String str="13651399999";
System.out.println(str.matches(regex));//返回true
匹配一个邮箱:
String regex="\\w+@\\w+([.]\\w+)+";
String str="sdfsq@qq.com.cn";
System.out.println(str.matches(regex));
切割:String类中的split(regex)方法
按照.切割:
String rex="[.]";
//String rex="\\.";
String[] arr=str.split(rex);
for(String s: arr){
System.out.println(s);
这两种表达式都可以切割。
按照叠词切割:
String str="sdfsq@qq.com.cn";
String rex="(\\D)\\1+";
String[] arr=str.split(rex);
for(String s: arr){
System.out.println(s);
替换:String类的replaceAll(regex,newString);
//给叠词替换成*
String str="dsfsddfaadddff";
String rex="(.)\\1+";
System.out.println(str.replaceAll(rex,"*"));
获取:将符合规则的字符串取出:
步骤:1,将正则表达式封装成对象。
2,让正则表达式对象与要操作的字符串想关联。
3,关联后,获取匹配引擎。
4,通过引擎对符合规则的字符串进行操作。
这四个步骤中要用到Pattern和Matcher对象。这两个对象在util.regex包中,因此首先要导入util。regex包。
Pattern对象没有构造方法,但静态的compile(rex)方法,因此可以通过这个方法获取到Pattern对象
Marcher对象通过Pattern对象的matcher()方法获取;当获取到Matcher对象后可以同过它的find(0方法判断是否有符合规则的字符串
如果有返回true否则返回false再通过group()方法获取到这个字符串。
例如:
结果为: