----------android培训、java培训、java学习型技术博客、期待与您交流!------------
一、String类
1.什么是String类?
String类用以描述字符串的这一类事物。在Java中字符串属于对象,Java提供了String类来创建和操作字符串。Java 程序中的所有字符串字面值(如 "abc"
)都作为此类的实例实现。
2.特点
1)字符串是常量,它们的值在创建之后不能更改。
2)String 对象是不可变的,可以进行共享。
注:如果需要对字符串做很多修改,那么应该选择使用StringBuffer或StringBuilder类。
3.创建字符串
创建字符串有很多种方式,其中最简单的创建方式格式如下:
String s="hello";
其中,"hello"表示一个字符串常量值,编译器会使用该值自动创建一个String对象。
特点:用该方式创建对象时,虚拟机会先在常量池中查找是否有相同字符串,如果有则将字符串的引用指向该字符串对象,不再创建新的字符串对象,相对于共享。如果没有则在常量池新建一个字符串对象。这种方式创建的字符串对象,能够保证在常量池中创建的对象始终唯一,不会存在两个相同的字符串对象,可以节约内存,体现了String类对象可以共享的特点。
例如:
String s1="abc";
String s2="abc";
那么s1和s2指向的就是同一个字符串对象,因为在创建s2指向的字符串对象时,发现常量池已经存在了相同的字符串对象,因此s2和s1指向了同一个字符串对象"abc"。
和其他对象一样,还可以通过关键字和构造方法来创建String对象。String类提供多种构造方法,这些方法提供不同的参数来初始化字符串,创建格式如下:
a)String(String original)
格式:String s=new String("hello");
b)String(char[] value)
格式:
char[] ch={ 'h', 'e', 'l', 'l', 'o'};
String s=new String(ch);
特点:该方式创建对象不再从常量池中进行查找,而是直接在内存中开辟空间,将字符串对象存入该内存空间中。这种方式建立对象在内存中存在两个对象,即new和“abc”。用该方式创建对象时,字符串的引用变量始终指向的不会是同一个字符串对象,也就是说指向字符串的内存地址不相同。
例如:
String s1=new String("abc");
string s2=new String("abc");
例中,s1和s2指向的不是同一个对象,虽然字符串对象内容相同,但存放的内存地址值不同,都是存放在用new的方式新开辟的空间中。
这里只列举了两种构造方法创建String类对象的方式,如需了解更多,可以参阅Java API文档。
4.常见的操作功能
1)获取
a)获取字符串的长度:
int length()
注:数组用的length,不要弄混淆。
b)根据位置获取位置上的字符:
char charAt(int index)
c)根据字符或字符串获取其在字符串中的位置:
int indexOf(int ch):返回指定字符在此字符串中第一次出现处的索引。如未找到,返回-1。
int indexOf(int ch,int fromIndex):返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索。如未找到,返回-1。
int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引。如未找到,返回-1。
int indexOf(String str,int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。如未找到,返回-1。,
int lastIndexOf(int ch):返回指定字符在此字符串中最后一次出现处的索引。如未找到,返回-1。
注:方法的参数类型为虽然int,但仍可接受字符类型的参数类型,只要不出现类型不兼容的现象即可。
2)判断
a)字符串中是否包含某一个字符串:
boolean contains(charSequence s):当且仅当此字符串包含指定的 char 值序列时,返回 true。
注:indexOf(String str)即可以判断是否包含,还可以获取出现的位置。但contains可以接受多个不同的对象,如String、StringBuffer等。
b)判断字符串是否有内容:
boolean isEmpty()
c)判断字符串是否以指定的前缀开始:
boolean startsWith(String prefix)
d)判断字符串是否以指定的后缀结束:
boolean endsWith(String suffix)
e)判断字符串内容是否相同:
boolean equals(Object anObject):复写了Object的equals方法。
f)判断字符串内容是否相同,并忽略大小写:
boolean equalsIgnoreCase(String anothingString)
3)转换
a)将字符数组转换成字符串
构造函数:
String(char[] value):分配一个新的 String,使其表示字符数组参数中当前包含的字符序列。
String(char[] value,int offset,int count);分配一个新的 String,它包含取自字符数组参数一个子数组的字符。offset为取的起始位,count为取的个数。
静态方法:
static String copyValueOf(char[] data):返回指定数组中表示该字符序列的 String。
static String copyValueOf(char[] value,int offset,int count):返回指定数组中表示该字符序列的 String。
static String valueOf(char[] data):返回 char 数组参数的字符串表示形式。
b)将字符串转换成字符数组;
char[] toCharArray()
c)将字节数组转成字符串:
String(byte[] bytes)
String(byte[] bytes,int offset,int count):将字节数组中的一部分转换成字符串。
d)将字符串转换成字节数组:
byte[] getBytes():使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
byte[] getBytes(Charset charset):使用给定的 charset 将此 String 编码到 byte 序列,并将结果存储到新的 byte 数组。
Charset(字符集):是一个体系援助的通盘笼统字符的集合。用来指定编码表,常见的编码表有:UTF8编码(国际化编码)、中文gbk编码、简体中文gb2312编码等。
e) 将基本数据类型转成字符串:
static String valueOf(int i):返回 int 参数的字符串表示形式。
static String valueOf(double d):返回 double 参数的字符串表示形式。
注:3+“”等同于String.valueOf(3),且字符串和字节数组在转换过程中,是可以指定编码表的。
f)字符串大小写转换:
String toUpperCase():将字符串中的小写字符全部转换成大写。
String toLowerCase():将字符串中的大写字符全部转换成小写。
4)替换
a)新字符替换字符串中的旧字符:
String replace(char oldchar,char newchar):如果替换不成功则返回原字符串。
b)新字符串替换旧字符串:
String replace(CharSequence target,CharSequence replacement):如果替换不成功则返回原字符串。
示例:String s="hello java";
s=s.replace("java","world");
System.out.println(s);
结果输出为:hello world。
5)切割
a)根据指定的字符串进行切割:
String[] split(String regex)
6)截取
a)截取字符串指定位置至结尾处:
String substring(int beginIndex):如果角标不存在,则会发生角标越界异常。
b)根据起点和终点位置截取字符串:
String substring(int beginIndex,int endIndex):包含头,不包含尾,注意避免角标越界。
7)比较和去空格
a)按字典顺序比较两个字符串:
int compareTo(String anotherString)
b)按字典顺序比较两个字符串,并不考虑大小写:
int compareToIgnoreCase(String anotherString)
注:如果参数字符串等于此字符串,则返回值 0;如果此字符串按字典顺序小于字符串参数,则返回一个小于 0 的值(此字符串的字符值减去参数字符串的字符值);如果此字符串按字典顺序大于字符串参数,则返回一个大于 0 的值。
c)去除字符串两端空格:
String trim():返回新的字符串。
5.练习
1.模拟一个trim方法,去除字符串两端的空格。
/*
练习1:模拟一个trim方法,去除字符串两端的空格。
思路:
1.用第一个指针从字符串的前端逐个字符遍历,记录下第一个不是空格的位置。
2.用第二个指针从字符串的后端逐个字符遍历,记录下第一个不是空格的位置。
3.用substring方法截取字符串中第一个指针的位置到第二个指针的位置加1的子字符串。
*/
class TrimDemo
{
public static void main(String[] args)
{
String s=" hello world ";
System.out.println(s);
s=trim(s);
System.out.println(s);
}
//定义一个函数,用来去除字符串两端的空格
public static String trim(String str)
{
char[] ch=str.toCharArray();
//定义两个指针
int pos1=0,pos2=ch.length-1;
//第一个指针记录字符串前端第一个不为空格的位置
while (ch[pos1]==' '&pos1<pos2)
{
pos1++;
}
//第二个指针记录字符串后端第一个不为空格的位置
while (ch[pos2]==' '&pos1<pos2)
{
pos2--;
}
//返回去除两端空格的字符串
return str.substring(pos1,pos2+1);
}
}
程序运行后的结果如下图:
2.将字符串全部反正和字符串的指定部分反转。
/*
练习2;将字符串全部反转,将字符串的指定部分进行反转。
思路:
1.将字符串变成字符数组。
2.定义两个指针,分别从两端遍历字符数组并交换位置。
3.将字符数组转换成字符串返回。
*/
class StringTest2
{
public static void main(String[] args)
{
String s="hello world";
System.out.println(s);
String s1=reverseString(s);
System.out.println(s1);
String s2=reverseString(s,0,3);
System.out.println(s2);
}
//反转全部字符串
public static String reverseString(String str)
{
return reverseString(str,0,str.length());
}
//反转字符串指定部分
public static String reverseString(String str,int a,int b)
{
char[] ch=str.toCharArray();
for (int x=a,y=b-1;x<y ;x++,y-- )
{
swap(ch,x,y);
}
return String.valueOf(ch);
}
//
public static void swap(char[] ch,int x,int y)
{
char temp;
temp=ch[x];
ch[x]=ch[y];
ch[y]=temp;
}
}
程序的运行结果如下图:
3.判断一个字符串在另一个字符串中出现的次数。
/*
练习3:判断一个字符串在另一个字符串中出现的次数。
思路:
1.先用valueOf方法判断并获取第一次出现的位置,定义计数器并累加1。
2.再从第一次出现的位置并加上所超找字符串的长度的位置开始查找第二次出现的位置,计数器加1.
3.重复上述过程,直到剩下字符串没有所查找的字符串时结束,此时返回-1。
*/
class StringTest3
{
public static void main(String[] args)
{
String s="aakdjaakdjfeaaaafjk";
int count=getSubCount(s,"aa");
System.out.println("count="+count);
}
public static int getSubCount(String str,String substr)
{
int index=0;
int count=0;
//循环判断所查找的字符串是否存在并获取该位置
while ((index=str.indexOf(substr,index))!=-1)
{
//将上一次查找的位置加上所查找字符串的长度作为新的查找起始位置
index+=substr.length();
count++;
}
return count;
}
}
程序运行后的结果如下图:
4.打印两个字符串中的所有最大相同字串。
/*
需求:打印两个字符串中的所有与最大相同子串。
思路:
1.将短的一个字符串与长的进行比较,如果没有,则将短字符串按长度递减的方式获取字串。
2.在长串中对每次获取的短字符串的字串进行判断,如果包含则打印,并记录该字串长度。
3.继续查找是否有同长度的字串,直到字串长度小于第一个找到的字串长度为止。
*/
class StringTest4
{
public static void main(String[] args)
{
String s1="hello java world";
String s2="jaca helloworld";
getMaxSubstring(s1,s2);
}
public static void getMaxSubstring(String s1,String s2)
{
String max,min;
int len=0;
max=(s1.length()>s2.length())?s1:s2;//获取长的字符串
min=(s1.length()<s2.length())?s1:s2;//获取短的字符串
for (int x=min.length()-1;x>0;x-- )//用短字符串的长度控制外循环
{
for (int y=0,z=x;z<min.length()+1; y++,z++)//按照长度递减的方式获取新的字串
{
String temp=min.substring(y,z);//获取短字符串子串
if(max.contains(temp))//如果长串包含,则表示找到
{
if (temp.length()>=len)
{
System.out.println(temp);
len=temp.length();
}
if(temp.length()<len)
{
return;//返回主函数
}
}
}
}
System.out.println("没有相同字串");
}
}
程序运行后的结果如下图:
从运行结果可以看出,最大的相同字串有两个,分别是hello和world。
二、StringBuffer类
1.概述
StringBuffer是线程安全的可变字符序列,类似于String的字符串缓冲区,可以理解为一个容器。
2.特点
1)能够被多次的修改,并且不产生新的未使用对象。
2)可以安全的用于多个线程。
3)长度是可变化的,可直接操作多个数据类型,最终通过toString方法变成字符串。
3.常见的操作功能
1)存储
StringBuffer append(CharSequence s):将指定的 CharSequence 追加到该序列。
StringBuffer insert(int offset,基本数据类型):将数据插入到指定的offset索引处。
2)删除
StringBuffer deleteCharAt():移除此序列指定位置的 char。
StringBuffer delete(int start,int end):移除此序列的子字符串中的字符。
3)获取
int length():获取StringBuffer的长度。
int indexOf(String str):返回第一次出现的指定子字符串在该字符串中的索引。
int indexOf(String str,int fromIndex):从指定的索引处开始,返回第一次出现的指定子字符串在该字符串中的索引。
int lastIndexOf(String str):返回最右边出现的指定子字符串在此字符串中的索引。
String substring(int start,int end):获取从索引start到end的字串,包含头,不包含尾。
4)修改
StringBuffer replace(int start,int end,String str):用字符串str替换从索引start到end的字串。
void setCharAt(int index,char ch):用字符ch替换索引index的字符,不返回StringBuffer。
5)反转
StringBufffer reverse():将此字符序列用其反转形式取代。
6)将指定字串存储到指定的字符数组中
void getChars(int srcBegin,int srcEnd,char[] ch,int dstBegin)
注:更多功能方法,请参阅java API文档。
三、StringBuilder类
StringBuilder类和StringBuffer类的功能一样,但两者的不同之处是StringBuilder不能保证同步,也就是会说StringBuilder用于多个线程会出现安全问题,因此StringBuilder常用于单线程情况。由于StringBuilder不需要同步,运行效率会比StringBuffer较高。
四、基本数据类型对象包装类
1.概念
就是将基本数据类型按照面向对象的思想封装成对象,从而实现更多的操作。
2.目的
1)可以定义更多的属性和行为对基本数据类型进行操作。
2)可以实现基本数据类型与字符串的转换。
3.基本数据类型对应的对象包装类
4.常见操作功能
1)基本数据类型转字符串:
a)基本数据类型+“ ”:如3+“ ”,运算后为字符串“3”。
b)基本数据类型包装类.toString(基本数据类型值):如Integer.toString(4),运算后为字符串“4”。即将整数4转化成了字符串“4”。
2)字符串转基本数据类型:
a)xxx 变量名=对象包装类.parseXxx(String str):
其中xxx为基本数据类型,Xxx为首字母大写的基本数据类型。
例:int a=Integer.parseInt("213"):将字符串"213"转换成整数213,但字符串格式必须符合int数据格式才能转,否则将发生NumberFormatException(数据格式异常)。
b)建立要转的基本数据类型对象包装类的对象,并初始化字符串,在利用对象去调用方法转换为基本数据类型。
例:Integer i=new Integer("34");
int a=i.intValue();
运算后的结果和上面的静态调用一致。但该方法为非静态方法,必须要用对象调用方式。如果对象有调用方法,则对象引用不能指向null,否则将发生NullPointerException。
3)进制转换
对于Integer、Long包装类:
a)十进制转其他进制:
static String toBinaryString(基本数据类型 参数名):以二进制(基数 2)无符号整数形式返回一个整数参数的字符串表示形式。
static String toOctalString(基本数据类型 参数名):以八进制(基数 8)无符号整数形式返回一个整数参数的字符串表示形式。
static String toHexString(基本数据类型 参数名):以十六进制(基数 16)无符号整数形式返回一个整数参数的字符串表示形式。
b)其他进制转十进制:
static int parseInt(String s,int radix):将 string 参数解析为有符号的 int,基数由第二个参数指定。
static long parseLong(String s,int radix):将 string 参数解析为有符号的 long,基数由第二个参数指定。
例如:parseInt("0", 10) 返回 0。
parseInt("473", 10) 返回 473。
parseInt("-0", 10) 返回 0。
parseInt("-FF", 16) 返回 -255。
parseInt("1100110", 2) 返回 102。
parseInt("99", 8) 抛出 NumberFormatException。
parseInt("Kona", 10) 抛出 NumberFormatException。
parseInt("Kona", 27) 返回 411787。
对于Float、Double包装类:
a)十进制转其他进制(十六进制):
static String toHexString(基本数据类型 名称):返回该基本数据类型参数的十六进制字符串表示形式。
注:不支持其他进制转十进制。
对于Boolean、Byte、Character、Short包装类:
a)其他进制转十进制(仅Byte、Short包装类支持):
static Byte parseByte(String s,int radix):将 string 参数解析为一个有符号的 byte,其基数由第二个参数指定。
static Short parseShort(String s,int radix):将 string 参数解析为一个有符号的 short,其基数由第二个参数指定。
4)自动装箱(jdk1.5升级新特性)
将一个基本数据类型(如char)的参数传递给需要一个对象包装类类型(如Character)参数的方法时,那么编译器会自动地将char类型参数转换为Character对象。像这种特征就称为装箱。
示例:Integer i=3;//编译器会自动装箱,1.5版本之后的写法
Integer i=new Integer(3);//1.5版本之前的写法
在装箱时,如果数值在基本数据类型(如int)范围之内,那么数值相同,不会产生新的对象,也就是说多个数值相同的引用指向同一个对象。
示例:Integer a=4;
Integer b=4;
那么引用b不会再创建新的对象,而是和引用a指向同一个对象。
5)自动拆箱(jdk1.5升级新特性)
将一个对象包装类类型(如Integer)参数与基本数据类型(如int)参数进行运算时,那么编译器会自动地将Integer对象转换为int类型参数再进行运算。像这种特征就称为拆箱。
示例:Integer i=5;//自动装箱
i=i+4;//自动拆箱
分析:i对象是不能直接和4进行相加,其实底层先将i对象转成int类型,再和4相加。
拆箱原理:就是先将i对象调用intValue()方法变成int类型,然后再与4相加。
6)判断对象的内容是否相同
boolean equals(Object obj)
示例:Integer a=new Integer(34);
Integer b=new Integer("34");
System.out.println(a.equals(b));
输出的结果为:true。因为equals比较的是两个对象的内容。
5.练习
面试题:"34 9 -7 67 25"要求对这个字符串中的数值进行从小到大的排序,生成一个数值有序的字符串。(必须会,代码略)