[Java学习日志]关于字符串的二三事

今天谈下字符串。


众所周知,字符串操作是计算机编程中最常见的操作,我们无时无刻不在和字符串打交道,因此了解字符串的一些行为对编程有巨大的好处。


一、不可变类.

首先我们从Java的可变类与不可变类开始。那么什么是可变类,什么是不可变类呢?
顾名思义,可变类指的是你可以改变该类的实例的内容,而不可变类即你不可以改变该类的实例的内容。

如:int i = 1; 我们可以改变整形变量i的内容,如使i = 2;
而如果有一个字符串,如String s = "Hello,world!"。其实,我们看似可以进行改变字符串内容的行为,如s = "Hello,again"。然而事实上我们知道,s其实为一个String类型的引用上诉看似改变其内容的行为事实上是再创建了一个叫做"Hello,again"的新字符串,然后将String类型引用s从"Hello,world!"上重新指向了该新字符串,并非是改变了字符串的内容,然后没有引用指向的字符串"Hello,world!"由Java垃圾处理机制处理。

在Java中,String类型属于不可变类,其对象是不可变的。其实当你查看Java源代码时就会发现,对于String类中的每一个看似修改其内容改的方法,实际上都是再创建了一个新的String对象,然后包含修改后的字符串内容。

如:下面是String类中连接字符串的concat方法源码:
    public String concat(String str) {
        int otherLen = str.length();
        if (otherLen == 0) {
            return this;
        }
        int len = value.length;
        char buf[] = Arrays.copyOf(value, len + otherLen);
        str.getChars(buf, len);
        return new String(buf, true);
    }
可以看到连接字符串的操作实际上也是再创建了一个新的字符串,在包含修改后的内容。

在Java中的可变类有如全部的基本类型,不可变类有如String类,基本类型的包装类等。

以上是关于字符串的一些基本内部原理。

二、关于字符串的一些操作的性能测试

下面进行了对于字符串的+号连接操作,concat方法连接操作,StringBuffer的append操作测试:
	String s1 = "abc";
	String s2 = "def";
		
		
		
	long start = System.currentTimeMillis();
	for(int i = 0; i < 100000; i++){
		s1 += s2;
	}
	long end = System.currentTimeMillis();
	long result = end - start;
	System.out.println("+号操作时间:"+result);
		
		
		
	s1 = "abc";
	start = System.currentTimeMillis();
	for(int i = 0; i < 100000; i++){
		s1.concat(s2);
	}
	end = System.currentTimeMillis();
	result = end - start;
	System.out.println("concat号操作时间:"+result);
		
		
		
		
	StringBuffer str = new StringBuffer("abc");
	start = System.currentTimeMillis();
	for(int i = 0; i < 100000; i++){
		str.append("def");
	}
	str.toString();
	end = System.currentTimeMillis();
	result = end - start;
	System.out.println("StringBuffer append操作时间:"+result);
得出结果为:

+号操作时间:11587
concat号操作时间:15
StringBuffer append操作时间:8

可以看到不同的方法拥有不同性能。

之前提到过String为不可变类,故其一些改变看似改变内容的方法操作实际上是创建了新的String类。而对于字符串连接操作,其内部实现也许使用的是列表也许使用了链表,由于各自采用算法的时间,空间复杂度不同,所以导致了性能差异。
不同的性能在实现应用复杂的功能时可能会带来一定影响。


以上便是在学习字符串时的一些了解和分享,若有不足,错误之处,望能给予指出批评。

你可能感兴趣的:(Java)