十七、字符串类型String(一)

String类

    我们知道java有八大基本数据类型,其中char是字符型,只能存放单个字符,如果我们想存放一串字符,就需要用到字符串String类型,字符串类型就是一个或多个字符组成的连续序列,程序需要存储的大量文字、字符都会使用字符串进行处理。


字符串String的声明

    String 变量名;

字符串两种实例化方式

1.使用字符串常量直接初始化(常用)

String str = "HelloWorld";

2.使用构造方法创建并初始化

String str = new String("HelloWorld");


字符串的拼接

    在前面的学习过程中我们经常使用到字符串的拼接输出,例如

System.out.println(name+"正在学习");

我们使用的都是"+"进行拼接,需要记住,字符串类型和所有的基本数据类型拼接都是字符串类型

代码演示:

package demo;

public class StringDemo {
	public static void main(String[] args) {
		String str1 = "Hello";
		String str2 = "World";
		int a = 10;
		double b = 20.0;
		boolean flag = true;
		System.out.println("我们的一串字符串拼接起来变成"+str1+","+str2+","+a+","+b+","+flag);
	}
}

代码运行结果:


代码讲解:在上面拼接过程中,如果两边都有字符串,中间夹着一个变量名我们就应该: "  "+变量名+"  ",

                 如果变量名是最后一个要拼接的元素,只需要一个"+"即可:"     "+变量名



字符串的比较

1."=="比较两字符串的引用地址是否相同

代码演示:

package demo;

public class StringDemo {
	public static void main(String[] args) {
		String str1 = "Hello";
		String str2 = "Hello";
		String str3 = new String("Hello");
		System.out.println(str1==str2);
		System.out.println(str1==str3);
	}
}

代码运行结果:


代码讲解:

  str1与str3不相同的原因:

(1)str1是变量名一定会保存在栈内存,而"Hello"就一定会在“堆内存中”。

(2)使用new创建对象,一定会在堆内存中开辟新的空间

(3)String本身是一个类,所以String类型是引用数据类型,String类的对象是一定可以进行引用传递的,引用传递的结果就是不同的栈内存将会指向同一块堆内存的地址。

(4)栈内存,里面存放的是数值,每一块栈内存只能保存一块堆内存的物理地址数值

不知道大家有没有注意过,bigdodo在给大家画内存空间图的时候,总会将堆内存画得比栈内存大,原因是这样:在栈内存中只存放堆内存的地址数值,而堆内存会存放内容,所以记得“栈小堆大”。

2."equals()"比较两个字符串是否相同,区分大小写

3."equalsIgnoreCase"比较两个字符串是否相同,忽略大小写

代码演示:

package demo;

public class StringDemo {
	public static void main(String[] args) {
		String str1 = "Hello";
		String str2 = "hello";
		System.out.println(str1.equals(str2));				//结果false
		System.out.println(str1.equalsIgnoreCase(str2));	//结果true
	}
}

4."compareTo"比较字符串的大小关系,两个字符串从第一个字符开始相比。

代码演示:

package demo;

public class StringDemo {
	public static void main(String[] args) {
		String str1 = "abc";
		String str2 = "abd";
		System.out.println(str1.compareTo(str2));  			//结果:   -1
	}
}

代码讲解:

    结果值为-1,这是因为字符串的大小比较,怎么比?只能通过字符对应的ASCII码的数值,进行比较,而且是从前往后一个一个比较。第一个都是"a",相等,第二个都是"b",相等,第三个,一个是“c”,一个是“d”,我们看下方的ASCII码的十进制,能看到99和100,前和后小了1,所以结果值为-1,大家还可以自己尝试一下别的值进行比较





字符串的的内存分配比较

1.直接赋值法

代码演示:

package demo;

public class StringDemo {
	public static void main(String[] args) {
		String a = "Hello";		//直接赋值
		String b = "Hello";		//直接赋值
		String c = b;			//引用传递
		
		System.out.println(a==b);		//true
		System.out.println(a==c);		//true
		System.out.println(b==c);		//true
	}
}

代码讲解:

    这里bigdodo给大家讲一下什么叫引用传递,我们都记得栈内存中存放的是堆内存的地址数值信息,也就是说,b = "Hello",中b存放的其实是个数值,是"Hello"所在堆内存空间的地址,所以当String c = b;引用传递,就是让c也指向了b所执行的物理地址数值

我们来个图再理解一下




我们可以看到"Hello"这个字符串,在String a = "Hello";的时候就一直在堆内存中占着一块地,如果只用直接赋值,和引用传递,并没有创建新的"Hello"字符串。


2.构造方法实例化

String str = new String("Hello");

内存空间图

代码讲解:我们能够看到,在new的时候,会先创建一个字符串"Hello",然后当做参数,再传给new出来的堆空间中,这样使用一次new,在堆空间中会出现两个"Hello",其中一个是垃圾



字符串一旦声明不可以改变

代码演示:

package demo;

public class StringDemo {
	public static void main(String[] args) {
		String str = "Hello";		//直接赋值
		str+="World";
		str = str + "!!!";
		System.out.println(str);
	}
}

代码运行结果

HelloWorld!!!

代码讲解:上述采用了字符串的拼接,看似结果是一个字符串,其实不是,我们来看一下内存空间



    

我们可以看到看似是一个字符串,完全拼接后,我们需要的只有一个字符串,却产生了4个字符串垃圾。如果一旦修改的数据量很大,而且对内存开销有要求,显然这种形式是不合理的,java还给我们提供了一个StringBuffer类让我们进行字符串打的大量修改操作



StringBuffer类

    同样可以用来使用字符串类型,String类型的大多数方法,同样可以使用,同时还提供了一些自己的方法。

StringBuffer专门用来对字符串的增删改查,对字符串的增删改查,而不会创建新的对象,对内存消耗上会比String类型小很多

我们来演示一下StringBuffer的一些方法:

代码演示:

package demo;

public class StringDemo {
	public static void main(String[] args) {
		StringBuffer sbf=new StringBuffer("Hello");
		sbf.append("World!!!");//类似字符串的拼接
		sbf.insert(0,"abc");//在开头位置插入abc
		sbf.delete(0,5);//删除下标从0到5且不包含5的字符  [0,5)
		String str = sbf.toString();		//确定sbf字符串修改完成后还能转换成String类型
		System.out.println(str);
	}
}

我们来对String类型,和StringBuffer类型,对字符串修改的时候,效率进行个比较

代码演示:

package demo;

public class StringDemo {
	public static void main(String[] args) {
		int n = 100000;
	    long start = System.currentTimeMillis();	//获取当前系统时间(单位:毫秒)
	    StringBuffer buf = new StringBuffer();
	    for (int i = 0; i < n; i++)
	           buf.append("abc");
	    long end = System.currentTimeMillis();
	    System.out.println("StringBuffer用时:"+(end-start)+"毫秒");

	    start = System.currentTimeMillis();	//获取当前系统时间(单位:毫秒)
	    String str = "";
	    for (int i = 0; i < n; i++)
	          str += "abc";
	    end = System.currentTimeMillis();
	    System.out.println("String用时:"+(end-start)+"毫秒");
	}
}

代码运行结果:


 代码讲解:我们可以看到,在效率上,同样执行100000次的操作,StringBuffer的执行效率是String类型的1195.5倍。这在对后期数据库操作的情况下,差距会更加的大。



总结点评:String类和StringBuffer类型的学习,主要是要知道它们在内存空间中都是怎么分配的,如果记住了,对String类型的学习帮助会很大,虽然StringBuffer类型在字符串的修改上执行效率比String类型高很多,但我们一般编程中都是使用String类型,因为我们很少会操作上万次的字符串的修改,为此,bigdodo还专门去做了实验,使用这两个类型进行10次的字符串修改,出来的时间都是0ms,整的bigdodo还以为自己写错了代码,而实际上,这两个类型在修改次数少的时候,效率都还是很高的,效率差可以完全忽略。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值