-----------android培训、java培训、java学习型技术博客、期待与您交流!---------
String类
字符串是一个特殊的对象,字符串一旦初始化就不可以被改变。
如:String s1 = "abc"; //s1是一个类型变量,"abc"是一个对象。
字符串是一个特殊的对象
下面我们通过一个程序来深入的了解字符串的特点
/*
通过程序来说明字符串的特点
*/
class StringDemo
{
public static void main(String[] args)
{
//定义字符串
String s1 = "abc";
String s2 = new String("abc");
String s3 = "abc";
//s1和s2不相等是因为他们是两个不同的对象
sop(s1 == s2);
//String类复写了Object中的equals方法,该方法用于判断字符串内容是否相同
sop(s1.equals(s2));
/*
s1和s3虽然为两个对象,但在s1出现时,"abc"已经在内存中存在,
s3在初始化时发现"abc"已经存在于内存中就不会单独开辟空间,浪费资源
因此为了节省空间,在字符串对象中,只要字符相同,引用型数据变量就指向同一个对象
*/
sop(s1 == s3);
/*
字符串一旦初始化就不可以被改变吗?
是的,但是为什么这里的s1输出的是123呢?
因为只是把"123"赋给了s1,"abc"还在内存中存在,它是个对象,不会消失
*/
s1 = "123";
//输出s1
sop(s1);
}
/*
这是一个输出方法,因为要输出才能看到结果,所以需要很多输出方法
如果一条一条大的话会降低效率,所以使用这个方法,
其中Object对象作为参数是通用的,因为Object是"上帝类"
*/
public static void sop(Object obj)
{
System.out.println(obj);
}
}
程序运行结果
面试题
在上面这个程序中s1和s2有什么区别?
是两个不同的对象就不说了,最大的区别在于
s1在内存中有的是一个对象,
s2在内存中有两个对象。
String类是用于描述字符串事物的,那么它就提供了多个方法,对字符串进行操作
常见操作(一定要全部掌握!!)
1. 获取
a. 字符串中包含的字符数,也就是字符串的长度
int length() 获取字符串长度
b. 根据位置获取位置上的某个字符
char charAt(int index) 获取指索引处的字符 (当方法访问到字符串中不存在的角标时会发生角标越界异常)
c. 根据字符获取该字符在字符串中的位置
获取ch在字符串中出现的位置 (没有找到ch,返回-1)
int indexOf(int ch) 返回的是ch在字符串中第一次出现的位置
int indexOf(int ch , int fromIndex) 从fromIndex指定位置开始,获取ch第一次出现的位置
int lasrIndexOf(int ch) 反向索引一个字符出现的位置
获取str在字符串中出现的位置
int indexOf(String str) 返回的是str在字符串中第一次出现的位置
int indexOf(String str , int fromIndex) 从fromIndex指定位置开始
2. 判断
a. 字符串中是否包含某一个子串
boolean contains(String str)
(特殊之处:indexOf(String str)可以索引str第一次出现的位置如果返回-1,表示该str不在字符串中存在,所以也可以用于指定
字符串的判断是否包含,如:if((x=str.indexOf("12"))!=-1)如果满足条件则是包含。而且该方法既可判断,又可获取str出现的位置,
如果只为判断,就使用contains方法,如果及判断又要获取位置,就用indexOf方法)
b. 字符串中是否有内容
boolean isEmpty() 原理就是判断长度是否为0
c. 字符串是否以指定内容开头
boolean startsWith(String str)
d. 字符串是否以指定内容结尾
boolean endsWitch(String str)
e. 判断字符串的内容是否相同
boolean equals(String str) String类复写了Object类中的equals,String类中的equals方法只为判断字符串内容是否相同
f. 判断内容是否相同,并忽略大小写
boolean equalsIgnoreCase() 判断字符串内容是否相同,并忽略大小写
3. 转换
a. 将字符数组转成字符串
构造函数方法
String(char[] value)
静态方法
static String copyValueOf(char[] value) 返回指定数组中表示该字符序列的 String
static String valueOf(char[] value) 返回字符数组的字符串表示形式
将字符数组中的一部分转成字符串
构造函数方法
String(char[] value , int offset , int cont)
静态方法
static String copyValueOf(char[] vlaue , int offset , int coutr)
b. 将字符串转成字符数组
char[] tocharArray()
c. 将字节数组转成字符串
String(byte[] bytes)
String(byte[] bytes , int offset , int count) 将字节数组中的一部分转成字符串
d. 将字符串转成字节数组
byte[] getByte()
e. 将基本数据类型转成字符串
static String valueOf(int i)
static String valueOf(double d)
//3 + "" ; //s.valueOf(3); (这两个一样,都是把基本数据类型数据转成字符串,就是写法不一样)
(特殊:字符串和字节数组在转换过程中是可以指定编码表的)
4. 替换
a. 替换字符串内的字符
String replace (char oldchar , char newchar) 返回一个字符串
它是通过newchar替换此字符串中出现的所有oldchar得到的,如果替换的字符不存在,返回的还是原来的字符串
b. 替换字符串内的某段字符
String replace(CharSequence target , CharSequence replacement)
5. 切割
a. 拆分字符串
String[] split (String regex) 将字符串通过regex拆分,并存入字符串数组中返回
6. 子串
a. 获取字符串中的一部分
String substring (int beginIndex) 获取从指定位置到字符串结尾的子串
String substring(int beginIndex , int endIndex) 从指定位置开始到指定结束位置的子串
(包含头不包含尾)
b. 获取全部
如:s.substring(0,s.length());
从0角标位获取到s.length()-1角标位的字符串子串,因为包含头不包含尾,所以参数内传入的结束为止角标要+1
7. 转换,除去空格,比较
a. 将字符串转成大写或小写
String toUpperCase() 转换为大写
String toLowerCase() 转换为小写
b. 将字符串两端的多个空格去除
String trim()
c. 对两个字符串进行自然顺序的比较
int compareTo(String anotherString) 按字典顺序比较两个字符串
下面来看上述方法的示例
import java.util.Arrays;
/*
对字符串进行常见操作的方法演示
在这里我演示平常比较常用的。
*/
class StringDemo
{
public static void main(String[] args)
{
//定义字符串
String s1 = "abcdefg";
String s2 = "123321";
String s3 = " hahah ";
//1.获取
//a.字符串长度
sop("s1长度为:"+s1.length());
//b.根据位置获取位置上的字符
sop("s1中3号角标位上的字符为:"+s1.charAt(3));
//c.根据字符获取它在字符串第一次出现的位置
sop("s1中e第一次出现的角标位:"+s1.indexOf("e"));
//2.判断
//a.字符串中是否包含一个字串
sop("s1中是否包含abc:"+s1.contains("abc"));
//b.字符串中是否有内容
sop("s1中是否有内容:"+s1.isEmpty());
//c.字符串是否以指定内容结尾(一般用于判断文件类型)
sop("s1是否以java结尾:"+s1.endsWith("java"));
//d.判断字符串中的内容是否相同
sop("s1中的内容是否与s2相同:"+s1.equals(s2));
//3.转换
//a.将字符串转换成字节数组
char[] c1 = s1.toCharArray();
sop("s1转化为字节数组:"+Arrays.toString(c1));
//b.将基本数据类型转换为字符串
sop("将987转换为字符串:"+String.valueOf(987));
//c.友情提示一个,在我做基础练习的时候遇到的
// 将字符串转为基本数据类型,以转为int类型为例
sop("将字符串465 转换为int类型:"+Integer.parseInt("465"));
//4.替换
//a.替换字符串中的字符
sop("将s1中的a替换成1:"+s1.replace('a','1'));
//5.切割
//a.拆分字符串
String[] arrs = s1.split("c");
sop("将s1从c拆分开"+Arrays.toString(arrs));
//6.获取子串
//a.获取字符串中的一部分
sop("获取s1字符串中的1-5号角标位上的字符串:"+s1.substring(1,6));
//因为获取角标位包头不包尾,所以获取到第5位,要在参数上写6
//7.转换
//a.将字符串都转为大写
sop("将s1都转为大写:"+s1.toUpperCase());
//b.将字符串两端的多个空格去掉
sop("本来的s3:"+s3+".......去掉空格之后的s3:"+s3.trim());
}
//定义一个输出方法,便于代码观看
public static void sop(Object obj)
{
System.out.println(obj);
}
}
运行结果
字符串练习一
/*
字符串练习
练习一
将字符串反转
思路:
将字符串转换为字符数组
将数组反转
把数组变回字符串
*/
class StringTest1
{
public static void main(String[] args)
{
//先定义一个字符串
String s1 = "2015年6月13日11:28:33";
//输出原来的数组
System.out.println("原数组为:"+s1);
//调用反转字符串方法反转字符串,并输出。
System.out.println("反转后的数组为:"+reverseString(s1));
}
//反转字符串的方法
public static String reverseString(String str,int start,int end)
{
//将字符串转换为数组
char[] arrc = str.toCharArray();
//调用反转方法,反转数组
charReverse(arrc,start,end);
//将数组变成字符串返回
return new String(arrc);
}
//反转字符串的方法,与上一个方法重载
public static String reverseString(String str)
{
//返回它的重载形式,相当于用于调用只有一个String类型参数的reverseString方法
//它把作为参数的str进行了解析,获取到字符串长度后
//返回重载方法,并把获取到的信息传入作为参数传入
return reverseString(str,0,str.length());
}
//反转方法
public static void charReverse(char[] arrc , int start , int end)
{
//遍历数组
for(int x=start , y=end-1 ; x<y ; x++,y--)
{
//调用交换数组元素方法
swap(arrc,x,y);
}
}
//交换数组元素的方法
public static void swap(char[] arrc, int start , int end)
{
char temp = arrc[start];
arrc[start] = arrc[end];
arrc[end] = arrc[start];
}
}
运行结果
字符串练习二
/*
字符串练习
练习二
获取一个字符串在另一个字符串中出现的次数
思路:
定义一个计数器
获取小字符串在大字符串中第一次出现的位置
然后从第一次出现的位置之后获取小字符串出现的位置,一直到没有小字符串出现为止
每出现一次计数器就+1,获取不到时,计数停止
*/
class StringTest2
{
public static void main(String[] args)
{
//定义一个大字符串
//你不能改变你的过去,但你可以让你的未来变得更美好。一旦时间浪费了,生命就浪费了。
String str="You cannot improve your past, but you can improve your future. "+
"Once time is wasted, life is wasted.";
//输出字符串
System.out.println("str = "+str+"\r\n"+
"你不能改变你的过去,但你可以让你的未来变得更美好。一旦时间浪费了,生命就浪费了");
//调用count计数方法,获取im在str中出现了几次,并输出
System.out.println("im出现的次数"+count(str,"im"));
}
//计数器方法,得到str字符串中,key字符串出现的次数
public static int count(String str,String key)
{
//定义变量,计数器
int count=0;
//定义变量,用于获取存放角标
int index=0;
//定义循环,获取key在index角标位后第一次出现的位置,如果返回值等于-1 说明字符串中再也没有key了,循环结束
while((index=str.indexOf(key,index))!=-1)
{
//每次循环index都变成index+key.length() 因为找到之后返回了key的位置,要从key字符串之后的位置开始找。
index = index+key.length();
//每找到一次计数器就自增一次。
count++;
}
//返回计数器的值
return count;
}
}
运行结果
字符串练习三
/*
字符串练习
练习三
获取两个字符串中最大相同字符串
思路:
将较短的字符串与长字符串比较,如果没有,则将较短的字符串按长度递减的方式获取
将每次获取的子串,去长字符串中判断是否包含,包含即找到。
*/
class StringTest3
{
public static void main(String[] args)
{
//定义一个较短字符串,一个长字符串
String s1 = "123abc";
String s2 = "sdfdsfe123a784wer";
//调用获取最大相同字符串的方法,并输出
System.out.println("s1和s2最大相同字符串为:"+getMaxSubString(s2,s1));
}
//获取最大相同字符串的方法
public static String getMaxSubString(String s1,String s2)
{
//定义两个String类型的变量
String max = "",min = "";
//利用三元运算符获取较长的字符串
max = (s1.length()>s2.length())?s1: s2;
//利用三元运算符获取较短的字符串
min = (max==s1)?s2: s1;
//外循环,控制在较短字符串长度内。
for(int x=0; x<min.length(); x++)
{
//内循环,y为初始角标位,z为结束角标位,通过y和z获取短字符串的子串,然后去看看长字符串中是否有短字符串的子串
//z = min.length()-x 是因为要找最大长度子串,所以子串的长度要依次递减
//z!= min.length+1 是因为获取子串包头不包尾,所以传入的参数要+1
for(int y=0,z=min.length()-x; z!=min.length()+1; y++,z++)
{
//获取较短字符串的子串
String temp = min.substring(y,z);
//判断如果较长字符串中有较短字符串的子串
if(max.contains(temp))
//则返回temp
return temp;
}
}
//没有找到则返回"没有找到相同字符"的语句
return "没有找到相同字符";
}
}
运行结果
StringBuffer类
StringBuffer是一个容器,字符串的组成原理就是通过该类实现的。StringBuffer可以对字符串内容进行增删改查等操作,很多方法和String相同
StringBuffer类的特点
1. StringBuffer的长度是可变的
2. 可以直接操作多个数据类型。
3. 最终会通过toString()方法变成字符串。
StringBuffer常见操作
1. 存储
a. 将指定的数据作为参数添加到已有数据的结尾处
StringBuffer append()
其中StringBuffer只是一个容器,所以它的对象可以往里面添加东西还是这个容器,不用新建对象
b. 将数据插入到指定的offset位置
String intsert(int offset ,
数据
);
2. 删除
a. 删除缓冲区中的数据,包含头不包含尾
StringBuffer delet(int start , int end)
b. 删除指定位置的字符
StringBuffer deleteCharAt(int index)
其中delete( 0 , s.length())表示清空缓冲区
3. 获取
a. 根据角标获取字符
char charAt(int index)
b. 获取字符串str第一次出现的位置
int indexOf(String str)
c. 反向获取str第一次出现的位置
int lastIndexOf(String str)
d. 获取缓冲区字符串的字串(与String类中的用法一样)
String substring(int start , int end)
4. 修改
a. 用新的字符串替换指定位置开始到指定位置结束的字符串
StringBuffer replace(int start , int end , String str)
b. 修改指定位置的字符串
void setCharAt(int index , char ch)
5. 反转
a. 将缓冲区字符串倒过来写
StringBuffer reverse()
6. 将缓冲区中指定数据复制到指定字符数组中
void getChars(int srcBegin , int srcEnd , char[] dst , int dstBegin)
在JDK1.5版本之后出现了StringBuilder
StringBuffer是线程同步的,效率较低,加了锁。
StringBuilder是线程不同步的,适用单线程,没有锁,效率高,用于多线程不安全。
单线程情况下,建议使用 StringBuilder可以提高效率,若果需要同步的话可以自己加锁。
Java升级的三大因素
1. 提高效率
2. 简化书写
3. 提高安全性
基本数据类型对象包装类
将基本数据类型封装成对象的好处在于
可以在对象中定义更多的功能方法操作该数据。基本数据类型对象包装类的最常见作用,就是用于基本数据类型和字符串类型之间做转换。
基本数据类型对应的基本数据类型对象包装类
byte Byte
short Short
int Integer
long Long
boolean Boolean
float Folat
double Double
char Character
基本数据类型转成字符串
1. 基本数据类型+“”;
如:318+"" ; //将318整数编程"318"
2. 基本数据类型.toString(基本数据类型值)
如:Inter.toString(318); //将318整数变成”318”.
字符串转成基本数据类型
xxxa = Xxx.parseXxx(字符串);
如:int a = Integer.paresInt(“132”); //将”132”转换为int型的132,paresInt()为静态方法,可以让基本数据类型包装类直接调用
Integer i = new Integer(“456”); //通过基本数据局类型包装类的构造函数,将字符串转成基本数据类型包装类对象
int num = i.intValue(); //跟上面的静态方法结果一样,但这种属于对象调用。
十进制转成其他进制
java.lang.Integer类中方法
static String toBinaryString(); //十进制转成二进制
static String toHexString(); //十进制转成十六进制
static String toOctalString(); //十进制转正八进制
其他进制转成十进制
java.lang.Integer类中方法
static int parseInt(String,radix);
如:int a= Intager.parseInt("3c",16); //将十六进制数3c转换为十进制
JDK1.5版本后出现的新特性
Integer x = 5; //会自动装箱,等效于 new Integer(5),并且x可以直接进行运算
x = x /*x.intValue() */ + 2; //自动拆箱,x变成了int类型,和2进行加法运算,再将和进行自动装箱赋给x /**/中为其实原理是这样代码 哈哈哈
注意:是Integer类型对象,所以可以出现null,编译通过,运行失败,因为x = null就不能隐式的调用intValue方法,
会出现空指针异常,所以要进行判断,不为null才能进行运算.
例:
Integer a = 128;
Integer b = 128;
a == b (false)
Integer x = 127;
Integer y = 127;
x == y (true)
这是为什么呢?
因为x和y指向了同一个Integer对象,当数值在byte范围(-128~127)内时,对于新特性,如果该值已经存在,则不会开辟新的空间。
课后作业
/*
作业:
"12 0 99 -7 30 4 100 13"
要求对字符串中的数值进行排序。生成一个数值从小到大新字符串。
"-7 0 4 12 13 30 99 100"
思路
将字符串切割成字符串数组
将字符串数组转成int类型数组
给int数组中的数字排大小
把int数组转为字符串输出
*/
class StringHomeWork
{
public static void main(String[] args)
{
//定义一个string类型变量,用于接收要排序的数组
String str = "12 0 99 -7 30 4 100 13";
//输出排序前字符串
System.out.println("排序前字符串:"+str);
//调用给字符串排序方法,给字符串排序,并输出
System.out.print("排序后字符串:"+sortString(str));
}
//创建字符串排序方法
public static String sortString(String str)
{
//先将字符串通过空格切割成字符串数组
String[] arrs = str.split(" ");
//定义一个int类型的数组,长度为str.length()
int[] arri = new int[arrs.length];
//遍历arrs数组
for(int x=0 ; x<arrs.length ; x++)
{
//将String数组中的元素转换为int类型,然后存入arri数组中
arri[x] = Integer.parseInt(arrs[x]);
}
//对int型的数组进行冒泡排序
for(int x=0 ; x<arri.length-1 ; x++)
{
for(int y=0 ; y<arri.length-1-x ; y++)
{
if(arri[y]>arri[y+1])
//调用替换方法,替换arri[y]和arr[y+1]的值
swap(arri,y,y+1);
}
}
//调用int类型数组转换成字符串的方法,并返回
return (intToString(arri));
}
//为了使代码看起来简便,单独定义替换方法
public static void swap(int[] arr , int a , int b)
{
int i = arr[a];
arr[a] = arr[b];
arr[b] = i;
}
//把int类型数组变为字符串的方法
public static String intToString(int[] arr)
{
//定义一个StringBuilder对象,用于接收字符串
StringBuilder sb = new StringBuilder();
//遍历数组
for(int x=0 ; x < arr.length-1 ; x++)
{
//定义一个String类型的变量,将int数组中的数组转为String类型后存入
String str = arr[x]+"";
//把字符串存入StringBuilder缓冲区中
sb.append(str+" ");
}
//到最后一个元素的时候单独存入StringBuilder容器中,后面不用加空格
sb.append(arr[arr.length-1]+"");
//将StringBuilder转化成String
String s = sb.toString();
//返回s
return s;
}
}
运行结果