Java养成计划(打卡第19天)
JAVA SE(夯实基础系列----Java初步)
今天和大家分享的时chapter five的内容,字符串,这个地方准备详细讲解一下,因为在我们的程序创建中使用比较频繁的类型。首先先提问几个基本问题引入:
前方高能
不是,基本数据类型就是boolean,整型4种(byte,short,int,long),浮点型,字符型四类8种,String类型是属于对象类型,位于java.lang
它是final类型的,不可以继承,修改,我们如果要进行修改,可使用StringBuffer类
没有变,因为String被设计成的不可变类,就是final类型的,原来指向对象的内存中是java,后面对这个字符串所作的修改就新构造了一个内存用来存储java study,并且让s变量☞向这个内存,但是原来的内存是没有变的,只是没有变量指向它了
创建了1个对象,首先我们要明确这里的"hello",“C”,“风"都是字符串常量,JVM在处理的时候就先优化为"helloC风”,之后在赋值给s,输出的结果就是helloC风
对于常量,系统直接存储它们的字面值,而不是它们的引用,那这里和上面的问题又有什么区别? 这里是创建对象,上面是修改对象,区别大着呢
首先一个一个看,就是最开始s = "hello"创建了一个,后面两个常量就直接识别,修改的时候就又创建了2个对象,所以是3个(手动狗头,错误请指正)
一个字符串可以是String或者StringBuffer的实例,但是String是不可修改的(immutable)侧重于字符串的比较,字符定位,字串提取,而StringBuffer类是可修改的,侧重于字符串中字符的添加、插入、设置等更改操作
StringBuffer和StringBuilder都是可进行更改操作的且不会产生新的对象,在实际操作中,如果需要有更改操作就要变换使用,其中StringBuffer是线程安全但是效率较低,StringBuilder不安全但是效率高,阅读源码就可以发现前者很多方法有synchronized修饰来保证安全
一个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.
Parameters:
value The initial value of the 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 oforiginal
is needed, use of this constructor is unnecessary since Strings are immutable.
Parameters: //也就是说因为String是不可修改的,所以这种方法就不必要使用
original A
String
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); //采用指定的字符集编码创建返回当前字符串各字符编码的字节数组,如UTF-8
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
提取是指从字符串中读得某个字符或者某个子串
定位是指从字符串中搜索某个字符或某个字串得位置
indexOf(int ch) 返回指定字符第一次出现得位置,你可能会疑惑为什么是int,因为’e’会被转换成int型
indexOf(String str) 返回字串str第一次出现的位置 ,如果找不到位置,就会返回-1(注意坐标不要越界)
同时也提供了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 = {"I","am","C","feng"};
String[] strs = {
"is","the","Now","am","Yes"};
// System.out.println(strs.length);
sort(strs);
for(String s: strs)
{
System.out.print(s +" ");
}
}
输出结果是
the is am Yes Now
还有就是判断两个字符串的内容是否相等的方法
其他的还有就去查阅文档就好了
valueOf() ;返回值类型都是String类型,可以将各种类型的数据都转换成String类型并返回,如果一个引用变量obj是空即null型文字,那么转换出来就是null型文字(这里也在文件IO实例中提到过)这是类方法,可以通过类名直接调用
我们之前就说过StringBuffer类就是一个可变长可修改的字符串对象,它是可修改的,主要侧重就是修改,使用String会产生一些对象浪费内存,我觉得其实就是C里面动态规划那样专门针对字符串对象
构造方法主要以下几种
长度是指该实例所表示字符串的长度,即当前所包含字符个数,而容量是指当前存储空间可表示的最长字符串的长度【动态内存】
比如原容量21 ,minmumCap为30, 21*2 +2 = 44 44>30,所以容量就是44
这里所有的方法都是直接修改的原实例,不会产生新的实例
还有一些其他的方法这里就不在赘述,简单举个例子
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);//比较后发现*2+2更大
System.out.println(sb.capacity());//新容量
sb.append(" nice to meet you");//会超过16
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
好啦,今天的分享就到这里,接下来的内容遇到这种面试中容易问到的还是会写出来,冲呀~