Java学习打卡:第十九天
Java养成计划(打卡第19天)
JAVA SE(夯实基础系列----Java初步)
内容管理
今天和大家分享的时chapter five的内容,字符串,这个地方准备详细讲解一下,因为在我们的程序创建中使用比较频繁的类型。首先先提问几个基本问题引入:
前方高能
基础面试题
String时基本数据类型吗?可以继承么
不是,基本数据类型就是boolean,整型4种(byte,short,int,long),浮点型,字符型四类8种,String类型是属于对象类型,位于java.lang
它是final类型的,不可以继承,修改,我们如果要进行修改,可使用StringBuffer类
String s = “java”; s = s+ " study",这两句代码执行后,原对象中数值变了吗?
没有变,因为String被设计成的不可变类,就是final类型的,原来指向对象的内存中是java,后面对这个字符串所作的修改就新构造了一个内存用来存储java study,并且让s变量?向这个内存,但是原来的内存是没有变的,只是没有变量指向它了
?String s = “hello” + “C” + “风”; 创建了几个对象?为什么?System.out.println(s)的结果是什么?
创建了1个对象,首先我们要明确这里的"hello",“C”,“风"都是字符串常量,JVM在处理的时候就先优化为"helloC风”,之后在赋值给s,输出的结果就是helloC风
对于常量,系统直接存储它们的字面值,而不是它们的引用,那这里和上面的问题又有什么区别? 这里是创建对象,上面是修改对象,区别大着呢
那么String s = “hello”,s = s+“C”+“风”;创建了几个对象?
首先一个一个看,就是最开始s = "hello"创建了一个,后面两个常量就直接识别,修改的时候就又创建了2个对象,所以是3个(手动狗头,错误请指正)
java中String类和StringBuffer类的区别
一个字符串可以是String或者StringBuffer的实例,但是String是不可修改的(immutable)侧重于字符串的比较,字符定位,字串提取,而StringBuffer类是可修改的,侧重于字符串中字符的添加、插入、设置等更改操作
java中SringBuffer和StringBuilder的区别?
StringBuffer和StringBuilder都是可进行更改操作的且不会产生新的对象,在实际操作中,如果需要有更改操作就要变换使用,其中StringBuffer是线程安全但是效率较低,StringBuilder不安全但是效率高,阅读源码就可以发现前者很多方法有synchronized修饰来保证安全
String类
一个String类的实例表示一个不可修改的字符串对象,加了修饰的,其中包含丰富的字符串创建、查询方法
构造方法
构造方法非常丰富,可以使用无参和其他很多类型的构造方法,可以在JDK的API文档中查询,我这里演示几种:
利用字符数组构造,利用字符串对象构造
需要注意的是:不管是一个字母还是一个汉字在Unicode编码中都是一个字符 ,大家在使用方法时要多看源码,多看解释
利用字符数组构造
Allocates a new String so that it represents the sequence of characters currently contained in the character array argument. The contents of the character array are copied; subsequent modification of the character array does not affect the newly created string.
利用原字符串构造
Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since Strings are immutable.
package FiveChapter;
public class StringDemo {
public static void main(String[] args) {
String s1 = new String();
char[] value = {'H','e','l','l','o','C','风'};
String s2 = new String(value);
String s3 = new String(s2);
System.out.println("the lenth of s1 is " + s1.length());
System.out.println("the lenth of s2 is " + s2.length());
System.out.println("the lenth of s3 is " + s3.length());
System.out.println("s2 = " + s2);
System.out.println("s3 = " + s3);
System.out.println("s2 ? s3 " + (s2 == s3));
System.out.println("s2 ? s3 " + (s2.equals(s3)));
}
}
运行结果是
the lenth of s1 is 0 the lenth of s2 is 7 the lenth of s3 is 7 s2 = HelloC风 s3 = HelloC风 s2 ? s3 false //这里s3是新创建的,虽然与原字符串内容相同,但是堆中地址不同 s2 ? s3 true
同时我们还要知道利用字节数组也是可以创建字符串实例的,这里就不演示了,可以去了解一下,同时有了实例,我们也可以调用实例方法得到包含该字符串各编码的字节数组
byte[] getBytes(String enc);
byte[] getBytes();
char[] value = {'H','e','l','l','o','C','风'};
String s2 = new String(value);
byte[] b;
b = s2.getBytes();
for(byte i:b)
{
System.out.println(i);
}
这样就会输出上面的字符数组的每一个字符的编码,10进制
72 101 108 108 111 67 -73 -25
提取,定位
提取是指从字符串中读得某个字符或者某个子串
- charAt(int index) 可以返回指定位置index上得字符char型
- substring(int beginIndex, int endIndex) 返回字符串中从某个位置beginIndex到另外一个位置endIndex得子串 String型
定位是指从字符串中搜索某个字符或某个字串得位置
同时也提供了lastIndexOf方法返回最后一次出现的位置
字符串中第一个的位置是0
这里就随便演示一下就好,毕竟还是挺简单的
char[] value = {'H','e','l','l','o','C','风'};
String s2 = new String(value);
System.out.println(s2.indexOf('e'));
这里输出的就是1,因为e就是在1位置
除此之外,还有很多提取定位的方法, 比如indexOf(String str, int fromIndex)返回fromIndex后面子串第一次出现的位置
比较
利用String中的方法进行字符串的比较,一般使用 compareTo(String anotherString) 比较与参数串的大小,小于参数串就返回值小于0
这里我们演示一下用冒泡排序排序一个字符串数组
package FiveChapter;
public class StringDemo {
public static void sort(String[] arr)
{
String t;
for(int i = 0;i < arr.length -1;i++)
{
for(int j = i;j < arr.length -i -1;j++)
{
if(arr[j].compareTo(arr[j+1]) < 0)
{
t = arr[j];
arr[j] = arr[j+1];
arr[j+1] = t;
}
}
}
}
public static void main(String[] args) {
String[] strs = {"is","the","Now","am","Yes"};
sort(strs);
for(String s: strs)
{
System.out.print(s +" ");
}
}
输出结果是
the is am Yes Now
还有就是判断两个字符串的内容是否相等的方法
- equals(Object object) 内容相同
- equalsIgnoreCase(String anotherString) 忽略大小写(填写验证码就有时候忽略大小写)
其他的还有就去查阅文档就好了
其他方法
- 连接 concat(String str) //将参数串连接在原串尾部产生一个新的字符串返回,如果要指代就将其赋值给原变量才行
- 替换 replace(char oldChar,char newChar) 将原串中所有的oldchar换成新的但是也是产生一个新串(之前的文件IO实例中就分析过这个问题)
- 去空 trim() 移除串前后端所有的空白字符产生一个新串返回,没有就返回本身
- 大小写转换 toLowerCase ,toUpperCase
类方法valueOf
valueOf() ;返回值类型都是String类型,可以将各种类型的数据都转换成String类型并返回,如果一个引用变量obj是空即null型文字,那么转换出来就是null型文字(这里也在文件IO实例中提到过)这是类方法,可以通过类名直接调用
StringBuffer类
我们之前就说过StringBuffer类就是一个可变长可修改的字符串对象,它是可修改的,主要侧重就是修改,使用String会产生一些对象浪费内存,我觉得其实就是C里面动态规划那样专门针对字符串对象
构造方法
构造方法主要以下几种
- StringBuffer() :默认的容量16,创建一个初始容量为16的不包含任何字符(length为0)的实例
- StringBuffer(int length) :创建一个容量为lenth的不包含任何字符的实例
- StringBuffer(String str) :由str对象的内容创建一个实例,实例的长度为str.length,容量为length+16【len和size真不一样】
len and size 长度和容量
长度是指该实例所表示字符串的长度,即当前所包含字符个数,而容量是指当前存储空间可表示的最长字符串的长度【动态内存】
- length() 返回当前的长度
- capacity() 可以返回该实例的当前容量
- setLength(int newLength) 可以改变一个StringBuffer类的实例的长度,将长度改变成新的长度,小于就裁剪,大于就加空字符(不是空白哦)
- ensureCapacity(int minmumCap)将容量扩大为max(minmumCap , 原长*2 +2)
比如原容量21 ,minmumCap为30, 21*2 +2 = 44 44>30,所以容量就是44
基本方法
- append(String str) 将str的内容添加至当前内容的尾部,重载的一系列,使用了valueOf转化,和String的concat一样,但是不会产生新的对象
- insert(intoffset, String str) 将str的内容插入到 当前buffer实例的指定位置(offset),也是重载的
- delete(int start,int end) 删除实例中指定位置的字符
- replace(int start,int end,String str) 将指定位置的字符替换为str
- reverse() 将当前实例总各字符的次序颠倒一下,原k位置的在n-k -1上,就将字符串倒序了
这里所有的方法都是直接修改的原实例,不会产生新的实例
还有一些其他的方法这里就不在赘述,简单举个例子
package FiveChapter;
public class StringDemo {
public static void main(String[] args) {
String s = "I'm Cfeng";
StringBuffer sb = new StringBuffer(s);
System.out.println(sb.capacity());
sb.ensureCapacity(40);
System.out.println(sb.capacity());
sb.append(" nice to meet you");
System.out.println(sb);
sb.insert(0, "Hello ");
System.out.println(sb);
System.out.println(sb.reverse());
}
}
运行结果
25 52 I’m Cfeng nice to meet you Hello I’m Cfeng nice to meet you uoy teem ot ecin gnefC m’I olleH
好啦,今天的分享就到这里,接下来的内容遇到这种面试中容易问到的还是会写出来,冲呀~
|