2019/7/11 17:29 二刷结束留念
10-StringBuffer(常见功能-添加)
说完了String,接下来我们来说StringBuffer,buffer是缓冲区的意思。我们都知道String字符串一旦粗现就不可以被修改,而StringBuffer可以用于修改~
StringBuffer是字符串缓冲区。是一个容器。
容器的特点:
C Creat U Update R Read D Delete
因此,StringBuffer的功能有:
1,存储。
2,删除。
3,获取。
4,修改。
5,反转。
1,存储。
StringBuffer位于java.lang包中。
注意它是final类,所以不能被继承喔。
我们发现,它有一大堆append方法:
StringBuffer append():将指定数据作为参数添加到已有数据结尾处。
试一下:
运行:
为什么打印结果一样捏?
我们再加一句:
试一下:
所以sb和sb1指向的是同一个对象。
这就是容器。
缓冲区有一个面盆理论,缓冲区就相当于那个面盆,不管往里面加面还是加水,还是那个盆。
所以其实不用像刚刚那样写,我们直接这样写就OK:
运行:
如果我们不想在字符串后面添加,想在前面添加呢?
满足你~
还有可以在前面添加的方法,不过不叫append了,它叫insert:
StringBuffer insert(index,数据):可以将数据插入到指定index位置。
我们试一下:
运行:
我们再试试,插入到角标为100的位置呢?
编译运行:
总结一下,StringBuffer的特点:
1,长度是可变化的。(数组也是容器,但长度不可变化)
2,可以直接操作多个数据类型。(数组一次只能操作一个数据类型)
3,最终会通过toString方法办成字符串。
什么时候用呢?
数据类型不确定、而且最终要变成字符串、而且最终个数也不确定的时候,缓冲区比数组要方便。(当然它俩各有利弊喔)
11-StringBuffer(常见功能-删除和修改)
添加说完说删除~
2,删除。
点进第一个看一下:
看一下,这里有注明,头是包含的,尾是不包含的。记住,在Java中,只要是需要取字符串一段,头都是包含的,尾都是不包含的哦。
StringBuffer delete(start,end):删除缓冲区中的数据,包含start,不包含end。
StringBuffer delete(index):删除指定位置的字符。
试一下哦:
运行:
现在想要将缓冲区的所有内容都删掉:
这样也不是不可以,但是把盆都扔掉了,换了一个新盆,所以太败家啦!
我们要勤俭持家呢:
有一个奇奇怪怪的想法:
这样会怎样呢?
运行试试:
什么都没删呢~
那这样呢?
这样就错了喔:
如果想删一个呢?不用使用这个方法,麻烦啦。用它:
3,获取。
这些都是我们的老朋友啦:
char charAt(int index);
int indexOf(String str);
int lastIndexOf(String str);
int length();
String substring(int start,int end);(注意这个方法我们也看很多遍啦,String类有,这个方法访问的还是String,不是StringBuffer)
因为它们的用法我们前面都学过啦,所以不再赘述~
我们接着看看修改:
4,修改。
说是修改,不如说是替换~替换掉原先字符串的内容。
StringBuffer replace(start,end,string);
试一下:
运行:
这是替换一串字符的方法,还有只替换一个字符的方法:
void setCharAt(int index,char ch);
注意它不返回StringBuffer,它是替换完就完事儿了,要小心哦。
试一下:
运行:
5,反转。
StringBuffer reverse();
这个方法也不赘述啦。
6,还有一个神秘方法,它是什么用处呢:
void getChars(int srcBegin,int srcEnd,char[] dst,int dstBegin );
我们试着使用一下:
运行结果:
所以,它的作用是,将缓冲区中的指定数据存储到字符数组中。
做了一个小标识表示了一下参数的意义:
12-StringBuilder
讲一个新的对象,StringBuilder。
注意,它是从1.5才开始的哦:
在JDK1.5之后出现了StringBuffer。
StringBuffer是线程同步。
StringBuilder是线程不同步。
我们该优先用哪个呢?
后者。
因为它是新出的,没有好处Java才不会出嘞,嘿嘿(☆_☆)/~~
认真说一下原因:
我们在使用一个容器的时候,如果还有另外的线程可以对它进行修改、删除之类的,那么这个数据在使用中就会错乱,并发就容易产生错乱哦。
如果我们在操作的时候,让它不能被其他线程动,这叫做同步,一次只有一个执行。是不是就有安全感多了呀?StringBuffer就是这样的,它是安全的。
而StringBuilder是不安全的。
那么为什么要选择StringBuilder呢?
因为如果是单线程程序,StringBuffer效率就会比较低(要判断锁),而StringBuilder就快捷很多。
所以,StringBuilder类中也有写到,它更适用于单线程,而多线程的时候建议使用StringBuffer:
Java的升级无非就是围绕以下三点:
1,提高效率。
2,简化书写。
3,提高安全性。
StringBuilder显然属于第一点。
在单线程开发中,还是建议使用StringBuilder,因此,刚刚的代码可以改成这样:
13-基本数据类型对象包装类
蛮重点的一部分~
按照Java面向对象的原则,Java将万事万物都视为对象,包括基本数据类型。
可是基本数据类型包装成对象有什么用呢?
以int类型为例,它是不是有自己的取值范围?是不是有多种进制表现形式?比如我们想把一种进制类型转换为其他进制的表现形式,怎么做呢?这个变起来是不是整数自己最清楚啦。
所以,如果把整数定封装成对象,里面定义这样的功能,我们指挥起来是不是就很方便啦?
所以,Java就这样做啦。
比如:
byte是基本数据类型,它有一个基本数据类型对象Byte,叫做引用数据类型。
同理,short对应short,int对应Integer,long对应Long,boolean对应Boolean,float对应Float,double对应Double,char对应Character。
我们还是以int为例来讲这个对象。
我们在java.lang包中找到Integer这个类:
当然,也看到了其他很熟悉的数据类型:byte呀,double呀,float呀,etc.
点进去:
把一个整数封装成一个对象,好处就体现出来啦。
首先,最大值和最小值是固定的值:
我们直接拿来用就好啦,就不用自己算啦。
试一下:
运行:
其实,基本数据类型包装类的最常见作用,就是用于基本数据类型和字符串类型之间做转换。
包括,基本数据类型转成字符串,字符串转成基本数据类型。
基本数据类型转成字符串:
有一个很简单的做法:基本数据类型+"";
但是我们有更专业的呢,Integer为我们定义了:
基本数据类型.toString(基本数据类型值);
如:Integer.toString(34);//将整数34变成字符串“34”
字符串转成基本数据类型:
我们在上网的时候,填写资料输入的都是字符串,而现在想判断其中的年龄是否大于20岁,就属于数学运算,所以此时就必须将字符串转成整数,才可以判断~
在Integer类中,这个方法叫:
演示一下:
运行:
而字符串转换成各种数据类型的方法基本都是:
xxx a=Xxx.parseXxx("......");
如,int a=Integer.parseInt("123");
double b=Double.parseDouble("12.23");
下面说两个比较特殊的:
第一个Boolean:
带双引号的"true"和不带双引号的true,绝对不一样喔。
boolean c=Boolean.parseBoolean("true");
字符类型Character没有parse....这个方法,因为它本身就是一个字符,并不是字符串哦。
会不会有这种情况,我们想要将并不是某种数据类型的字符串,转换成那种数据类型?
比如:
加上a之后,这个字符串就不是一个整形的数据了。
运行之后会报错哦,数字格式异常:
进行进制转换。
十进制转换成其他进制:
toBinaryString();
toHexString();
toOctalString();
使用一下,十进制转二进制:
运行:
十进制转十六进制:
运行:
其他进制转换成十进制:
使用一下:
运行结果:
再换一下:
运行,:
再试试十六进制~
运行:
能看出来了8~使用应该没问题喔~
注意,这样写会报错哦:
对啦,刚刚那个字符串转换成数据,讲的都是静态的方法。
我们也可以将数据封装成,比如说Integer对象,这个时候就有一个intValue方法:
它也可以将Integer类型对象转换成int类型的值。
例:
Integer i=new Integer("123");
int num=i.intValue();
14-基本数据类型对象包装类新特性
这种情况下,结果会是什么呢?
运行结果:
接下来介绍一下JDK1.5版本以后出现的新特性。
自动装箱。
自动拆箱。
自动拆箱的原理:
注意,1.5之后,它还可以为null:
但是在这个例子中,因为后面有一个x+2的运算,所以运行失败了:
所以,有了新特性之后,它的健壮性会差一点,使用之前不要忘记判断是否为空,当它不为空的时候才能做运算~为null要小心,会抛控制异常,一抛控制异常,程序就会停掉,因为它属于Runtime异常。
再介绍一个小的新特性~
先给例子:
运行结果:
都是数,怎么就差这么大呢?
因为a和b指向了同一个Integer对象。
127在byte范围内,对于新特性,如果该数值已经存在,则不会再开辟新的空间。
注意看~127和128的最大区别在于,127是byte类型数据范围的临界点(-128~127),127在这个范围内,它为了节省内存就不会开辟新的内存空间,超过这个范围,它就会开辟新的内存空间。
所以,在这个例子中,Integer a=127;之后,127已经在内存空间当中了,当再次Integer b=127;之后,b就直接指向原有的127对象,就不会再建立新的对象了~
面试中可能会用的小tips,开发中一般不会刻意这样判断~
另外,Integer还有这样一个方法:
数字能不能比较排序?
可以呀。
比如1在2前面,2在1后面,1和1相等,都是ASCII码排序。