黑马程序员----论String,StringBuffer,StringBuilder,基本数据类型对象包装类

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


1.String类

字符串是我们日常中最常用的一种数据类型,java肯定不会放过把它封装成对象的。出于面向对象的思想考虑,这样也确实是更方便我们程序员对字符串进行操作。java中字符串是常量,也就是说赋值一次就不能再改变其内容了。对于这个问题我个人觉得是因为开发java语言的大神觉得对于字符串来说,更多的操作是获取,查询等。只是访问,而没有修改其内容的操作,那么对于这种情况来说,将字符串存放到常量池中无疑是效率更高的一种方式。例如String str1="123";String str2="123";这时str1和str2指向同一个字符串对象,也就是说当我们创建一个字符串对象时,编译器不会立马就傻乎乎的去创建一个"123",而是先去常量池中找看看有没有"123",如果没有再创建,如果有,那么返回这个已经存在的对象的地址。
测试常量池存储方式:
/*
字符串常量存储在常量池中,常量池在方法区中,
例如先在其中存入"abc",如果又需要存入一个"abc",那就不用开辟新的空间了,直接将原来
的"abc"的地址拿来用就可以了,节省空间。
*/
package com.helong.stringdemo;
class StringDemo 
{
	public static void main(String[] args) 
	{
		String str1="abc";
		String str2="a"+"c"+"b";
		String str3="def";
		String str4="abc"+"def";
		System.out.println(str1==str2);
		System.out.println(str2==str4);
		System.out.println(str3==str4);
		System.out.println("Str1:"+str1+"....."+str1.hashCode());
		System.out.println("Str2:"+str2+"....."+str2.hashCode());
		System.out.println("Str3:"+str3+"....."+str3.hashCode());
		System.out.println("Str4:"+str4+"....."+str4.hashCode());
	}
}
运行图:


String常用方法:

1.获取
a.int length();该方法返回当前字符串对象的长度。
通常用于遍历字符串等对字符串进行循环操作的语句中
b.char charAt(int index);获取指定位置的单个字符。
通常用于对字符串中每个字符挨个进行操作时取出对应位置的字符
c.获取指定字符/字符串在字符串中第一次/最后一次出现的位置,不存在返回-1。
1.indexOf(char ch);
2.indexOf(char ch,int fromIndex);从位置fromIndex开始查找
3.indexOf(String str);
4.indexOf(String str,int fromIndex);
通常用于字符串的匹配,例如一个串中包含另一个串,可以操作文件名判断其文件类型indexOf(".java")
d.获取当前字符串对象的子串。
1.String substring(int start);
2.String substring(int start,int end);
通常用于对字符串进行取其所有子串的操作


 2.判断
a.boolean contains(String str);该方法用于判断当前字符串中是否包含str
通常用于文件检测,例如非法字符,敏感字的查询,关键字搜索等。
如果我们只是需要判断一个字符串是否包含另一个使用contains,但是如果还想要在字符串中的位置,那么就需要使用indexOf方法了。
b.boolean equals(String str);该方法用于判断两个字符串是否相等,这个方法复写了Object中的equals方法,重定义了内容,比较的是两个字符串的值,而不是引用。
通常用于字符串的比较,例如用户名密码的判断等等。
c.boolean equalsIgnoreCase(String str);功能与equals相似,只是这个方法忽略大小写。
通常用于字符串的比较,且忽略大小写的地方,例如邮箱验证等不是大小写敏感的地方。
d.boolean startsWith(String str);该方法用于判断当前字符串是否以str开头。
通常用于判断文件的类型,例如我们写java文件时,跟Array有关的文件名都以Array开头。
e.boolean endsWith(String str);该方法用于判断当前字符串是否以str结尾。
通常用于判断文件的类型,通过判断文件名的后缀名,例如"demo.java".endsWith(".java");

3.转换
a.通过构造函数将字符数组和字节数组转换成字符串。
b.static String copyValueOf(char[]);
c.static String copyValueOf(char[],int offset,int count);将数组中的全部/部分内容转成字符串。
d.static String valueOf(****);将各种类型(数组,基本数据类型,Object)转为字符串。
e.String toLowerCase();将当前字符串转为全小写。
f.String toUpperCase();将当前字符串转为全大写。
g.char[] toCharArray();将当前字符串转换成数组。
h.byte[] getBytes();将当前字符串转为字节数组。
i.String[] split(String str);将字符串按照str进行分割,返回字符串数组。
j.String replace(old,new);将字符串中的old用new替换(字符或者字符串)。
k.String concat(String str);将str添加到字符串的结尾。
l.String trim();去除字符串两端的连续空格。
m.compareTo(String str);按照字典序对两个字符串进行比较,返回0表示相等,返回正数表示当前字符串大,返回负数表示参数字符串大。
转换的方法通常用于对字符串进行某些更细致的操作时,这时使用数组可能更方便,且由于字符串是不可变的,因此通常我们转为数组,
对其操作完再转回成字符串。valueOf这个方法主要用于将各式各样的类型转为字符串方便打印输出等。replace可以用于文件编辑工具的
查找替换功能。trim主要用于在用户输入了用户名时去除两边的空格再判断用户名是否对错(前提是默认用户名不包括空格),
这样更人性化,否则很可能用户不明白为什么他的用户名明明看起来是对的,但是却是错的。compareTo用于字符串的大小比较,
这很重要,因为在很多地方,例如欧美国家等,很多东西的顺序都是按照字典序排列的,这个方法在这里就非常实用。


String类练习代码:

/*
测试String类的常用功能:
1.获取
2.判断

1*.获取
	1.1获取长度,获取字符串长度通过length()方法来实现的,不同于数组的length属性
	1.2获取对应位置的字符,charAt()
	1.3根据字符获取其首次出现位置,二次出现位置indexOf(int ch)
	1.4根据字符串获取其首次出现位置,二次出现位置indexOf(String str)

2.判断
	2.1是否包含某段内容contains(CharSequence)接收一个接口类型,该接口已知子类有char数组,String,stringBuffer,StringBuilder
		indexOf也能实现该功能:if(str.indexOf(str)!=-1)存在
		只需要判断使用contains,即要判断又要位置使用indexOf
	2.2是否为空isEmpty()
	2.3是否为某段开头startsWith(String)
	2.4是否为某段结尾endsWith(Strint)
	对文件名进行判断筛选。
	2.5判断内容是否相同equals,复写Object的方法
	2.6equalsIgnoreCase(),判断内容是否相同,且忽略大小写
c.装换
				1.static String copyValueOf(char[])//字符数组-》字符串
				2.char[] toCharArray();//字符串-》字符数组
				3.static String valueOf();//基本数据类型-》字符串
				4.byte[] getByres();
				字符串和字节数据转换中,可以设置编码方式;
d.替换
	1.String replace(char ordchar,char newchar);
	2.String replace(CharSequence ord,CharSequence new);
e.切割
	1.String[] split()
f.子串
	String substring(int begin);
	String sbustring(int begin,int end);从begin到end-1处
g.转换,去除空格,比较
	1.转换大小写,toLowerCase(),toUpperCase();
	2.去除两端多个空格trim();
	3.比较自然顺序的两个字符串compareTo();如果相等,返回0,否则返回不等的那两个字符相减的值
		如果为负数,说明该字符串小于参数字符串,正数表示大于参数字符串;
*/
package com.helong.stringmethodtest;
class StringMethodTest 
{
	public static void method_get()
	{
		String str="abcdefabcdkwertaasdfsdfaweta";
		print(str);
		//获取长度
		print(str.length());

		//对应位置的字符
		print(str.charAt(5));

		//对应字符出现的首次位置
		print(str.indexOf('a'));
		//对应字符出现的二次位置
		print(str.indexOf('a',str.indexOf('a')+1));
		//对应字符出现的所有位置
		for(int i=0;i<str.length();)
		{
			i=str.indexOf('a',i);
			if(i==-1)
				break;
			print(i);
			i++;
		}
		//反向索引,查找字符串中最后一个'a'
		print(str.lastIndexOf('a'));
	}

	public static void method_is()
	{
		String filename="StringDemo.java";
		//判断是否以String开头
		print(filename.startsWith("String"));
		//判断是否为Demo类文件
		print(filename.contains("Demo"));
		//判断是否为java文件
		print(filename.endsWith(".java"));
		//判断是否为空字符串
		print(filename.isEmpty());
		//判断字符串是否相等
		print(filename.equals("stringdemo.java"));
		//忽略大小学判断是否相等
		print(filename.equalsIgnoreCase("stringdemo.java"));
	}
	private static void print(Object obj)//如果传入基本数据类型,例如1,那么在1.5之后会经过装箱进行类型提升。
	{
		System.out.println(obj);
	}
	public static void main(String[] args) 
	{
		method_get();

		method_is();
	}
}

运行图:



String类总结:
String是一个功能非常齐全,实用非常强的一个类,如果我们不会对字符串进行很多的修改操作,那么建议使用String类,由于常量池的存在,使得这个类在不频繁创建对象的时候效率比较高,也能完成绝大部分的功能需求。


2.StringBuffer

这是一个容器类,线程安全的,拥有容器的一般功能,且能操作多种数据类型,更实用的是它的长度是可变的,也就是所用空间是动态分配的。String只适合那些不需要对字符串进行大量修改的场合,否则会大量的创建String对象,占用大量内存,效率极低,于是java提供了StringBuffer类来满足这些场合,假如我们写一个文件编辑器之类的软件,那么该类就会被大量的使用。

StringBuffer常用方法:

a.存储
1.StringBuffer append(****);该方法用于在字符串结尾添加数据。之所以返回值为StringBuffer我个人认为更多的是为了使得这个方法可以使用链式编程,例如sb.append(123).append('a').append("qwe");而为了将返回值赋给一个StringBuffer引用我觉得不是主要的。
通常用于从某个数据源获取数据,然后通过链式编程将数据全部添加到StringBuffer中。
2.StringBuffer insert(index,****);该方法用于在字符串index位置插入数据。
通常用于文本编辑器等的插入功能时,在指定地方插入指定的字符串。


b.删除
1.StringBuffer delete(start,end);该方法删除start到end-1的所有字符。
通常用于删除部分字符,也可以用于清空缓冲区,例如:sb.delete(0,sb.length());
2.StringBuffer deleteCharAt(index);该方法删除指定位置的一个字符。本质上这个方法也是内部也是调用的delete,例如deleteCharAt(index)内部调用delete(index,index+1);
通常用于删除指定位置的字符,可以用于密文的解密,比如在原文中每隔4个字符加一个a,使用这个方法去除这些a还原成原文。


c.获取
1.int length();获取长度。
2.char charAt(int index);获取指定位置的字符。
3.int indexOf(****);获取StringBuffer中字符串的首次出现位置,-1表示不存在,可以设置查找位置
4.int lastIndexOf(****);同上,不过获取的是最后一次出现的位置。
5.String substring(start);获取StringBuffer从start开始到最后的子串。
6.String substring(start,end);获取StringBuffer从start到end-1的子串。
通常用于对字符串进行检索等操作,例如查找某个关键字,敏感词等,获取长度一般用于循环遍历字符串中的循环判断条件。


d.修改
1.StringBuffer replace(start,end,str);将start到end-1的字符串使用str替换,返回StringBuffer的原理同append,为了使用链式编程。
通常用于文本编辑工具的替换功能,同样可以用于密文的生成和还原。
2.void setCharAt(index,ch);使用ch替换原串中index位置的字符。该方法特殊在其返回值类型为void
替换指定位置的单个字符时使用该方法。

e.反转
1.StringBuffer reverse();将字符串反转,例如:"123"-->"321"。
用于反转一个字符串,通常用于大部分的文本编辑功能。


StringBuffer类练习代码:
package com.helong.stringbufferdemo;
class StringBufferDemo
{
public static void main(String[] args) 
{
method_save();
method_get();
method_del();
method_upd();
}
//获取
private static void method_get()
{
StringBuffer sb = new StringBuffer("123456785747434577777345");
sop("sb长度:"+sb.length());
sb.append(23.23);
sop("sb长度:"+sb.length());
sop("位置3的字符:"+sb.charAt(3));
sop("sb中345的位置:"+sb.indexOf("345"));
sop("sb中345的位置:"+sb.indexOf("345",5));
sop("sb中345的位置:"+sb.lastIndexOf("345"));
sop("sb子串3-12:"+sb.substring(3,12));
}
//存储
private static void method_save()
{
StringBuffer sb=new StringBuffer();
sb.append(12).append('a').append("\thelong\t").append(12.23);
sop(sb.toString());

sb.insert(3,"ldy").insert(0,true);
sop(sb.toString());
//实际使用:
StringBuffer sb1=new StringBuffer();
sb1.append("Array").append("Demo").append(".java");
sop(sb1.toString());
}
//删除
private static void method_del()
{
StringBuffer sb=new StringBuffer("helong love ldy");
sop(sb);
sop(sb.delete(1,5));
sop(sb.deleteCharAt(8));
sop("("+sb.delete(0,sb.length())+")");//清空缓冲区
}
//修改
private static void method_upd()
{
StringBuffer sb = new StringBuffer("Arraydemo.javv  Arraydemo.javv  Arraydemo.javv  Arraydemo.javv");
sop(sb);
//将字符串中所有的javv改为java,对大量文本进行修改
for(int i=0;i<sb.length();i++)
{
	int index=sb.indexOf("javv",i);
	if(index!=-1)
	{
		sb.replace(index,index+"javv".length(),"java");
		i+="javv".length()-1;
	}
}
sop(sb);
//sop("sb4位置修改为l:"+sb.setCharAt(4,'l'));
//上语句报错,因为setCharAt方法返回值是void类型
sb.setCharAt(4,'l');
sop("sb4位置修改为l:"+sb);
}
private static void sop(Object obj)
{
System.out.println(obj);
}
}
运行图:



StringBuffer类总结:
我个人觉得StringBuffer类的使用的范围要更广于String,因为在绝大部分地方我们都需要对字符串进行修改等会改变其内容的操作,而StringBuffer的可变长度很好的应对这个问题,而不用像String类一样,频繁的创建对象,消耗内存。

3.StringBuilder

1.5以后出现的新类,该类作为StringBuffer的一个简易替代类,拥有和StringBuffer一模一样的功能方法,且由于该类不是线程安全的,因此不用每次都判断锁,因此效率更高,如果直接使用只适用于单线程。如果想在多线程中使用,可以利用Lock来手动同步,因此建议使用StringBuilder替代StringBuffer类。

相比:
1.StringBuilder是线程不安全的,但是效率高,因为它不考虑多线程迸发冲突的问题,通常用于单线程
2.StringBuffer是线程安全的,可以理解为它自带了锁机制,因此java建议多线程时使用StringBuffer,当然我们可以使用StringBuilder+Lock来解决线程安全问题。
3.开发建议使用StringBulider,遇到多线程,手写Lock解决,效率第一

java升级的目的:
1.提高效率。
2.简化书写。
3.提高安全性。


由于其是StringBuffer的简易替换类,因此它的方法与StringBuffer一模一样,就不在此演示了。


StringBuilder类总结:
1.在没有大量修改字符串的场合使用Stirng类。
2.在有修改字符串的场合使用StringBuffer类,但是在JDK1.5之后推出了StringBuilder类,该类效率更高,且安全性可以通过程序员手动解决,因此推荐使用StringBuilder类。

4.基本数据类型对象包装类

为什么我们要将基本数据类型也封装成类呢?其实这个问题很好理解,例如对于整型来说,有很多的操作可以做,比如将一个整型转换成其他类型,或者将其他类型转成整型,又或者比较两个整型的值,又或者进制转换等等。如果只有简单的基本数据类型,那么这些工作就需要我们自己去做,这不符合面向对象的编程思想,因此java将这些基本数据类型也封装成了类,这样更方便我们对这些数据进行操作。

1.基本数据类型与包装类的对应:



2.进制转换

十进制转其他进制
Integer.toBinaryString,toHexString,toOctalString
其他进制转十进制
Integer.parseInt("110",10);将"110"按照十进制转换成int
Integer.parseInt("3c",16);将"3c"按照十六进制转换成int

3.基本数据类型转成字符串

有两种方式:
方式1:23+"",任何基本类型与字符串相加都得到一个字符串,这里要注意一点:例如23+1+""和“”+23+1的不同,前者结果为字符串"24",后者为字符串"231",这是因为前者先是23与1相加得到24,再+""得到字符串"24",而后者先是""加上23得到字符串"23",再加上1,得到字符串"231",关键在于结合顺序
方式2:Integer.toString(23);这是调用了Integer类的静态方法


4.字符串转为基本数据类型

以字符串转成int为例:
int Integer.parseInt("34");


5.JDK1.5两个新特性

自动装箱,拆箱:
Integer i=new Integer(4);等价于Integer i=4;自动装箱特性。这个升级特性目的:简化书写
--自动装箱-->new Integer(4)
i=i+4;自动拆箱,i变为int型和4运算,再把结果装箱再赋给i。
--自动拆箱-->i.intValue(),再自动装箱new Integer(结果)
 。

byte范围数值存放到常量池中:
Integer m=128;
Integer n=128;
Integer x=127;
Integer y=127;
m==n;结果为false,正常,因为它们指向两个对象。
x==y;结果为true,这个是1.5新特性,当数值处于byte范围时(-128-127),如果该数值已经存在
那就再使用到的时候就不开辟新看空间了。Integer y=127;相当于Integer y=x;所以结果为true。

6.基本数据类型对象包装类练习代码:

//测试基本数据类型对象包装类
package com.helong.test;
class Test 
{
	public static void main(String[] args) 
	{
		//1.基本数据类型转为字符串的两种方式
		System.out.println(((23+"") instanceof String));
		System.out.println(((Integer.toString(23)) instanceof String));

		//2.基本数据类型与字符串相加的注意事项
		System.out.println(23+1+"");
		System.out.println(""+23+1);

		//3.字符串转为基本数据类型
		System.out.println(Integer.parseInt("22556"));

		//4.进制转换
		System.out.println(Integer.toBinaryString(123));
		System.out.println(Integer.toHexString(123));
		System.out.println(Integer.toOctalString(123));

		System.out.println(Integer.parseInt("1110011",2));
		System.out.println(Integer.parseInt("5567",8));
		System.out.println(Integer.parseInt("88c",16));

		//5.自动装箱,拆箱
		Integer a=2;//自动装箱2--->new Integer(2)
		a=a+1;//先是自动拆箱,再自动装箱:a--->a.intValue(),值+1--->new Integer(值+1)

		//byte范围问题
		Integer x=128;
		Integer y=128;
		Integer z=127;
		Integer v=127;//127还在-128~127范围内

		System.out.println(x==y);//结果为false
		System.out.println(z==v);//结果为true


		
	}
}
运行图:


我们可以看到,此处试验了JDK1.5的两个新特性。
特性1:自动装箱,拆箱。升级目的:简化书写。
特性2:byte范围数值对象存放在常量池中。升级目的:提高效率。


------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值