String,无所不在的数据类型

String对象是JAVA语言中重要的数据类型,但是不是基本数据类型,属于引用数据类型

任何一Project中,无疑字符串的操作是最多的了

String的内部结构:char数组,offset偏移量,count长度

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence
{
    /** The value is used for character storage. */
    private final char value[];

    /** The offset is the first index of the storage that is used. */
    private final int offset;

    /** The count is the number of characters in the String. */
    private final int count;
<span style="white-space:pre">	</span>。。。
 public String() {
        this.offset = 0;
        this.count = 0;
        this.value = new char[0];
    }
public String(String original) {
        int size = original.count;
        char[] originalValue = original.value;
        char[] v;
        if (originalValue.length > size) {
            // The array representing the String is bigger than the new
            // String itself.  Perhaps this constructor is being called
            // in order to trim the baggage, so make a copy of the array.
            int off = original.offset;
            v = Arrays.copyOfRange(originalValue, off, off+size);
        } else {
            // The array representing the String is the same
            // size as the String, so no point in making a copy.
            v = originalValue;
        }
        this.offset = 0;
        this.count = size;
        this.value = v;
    }
 public String(char value[]) {
        int size = value.length;
        this.offset = 0;
        this.count = size;
        this.value = Arrays.copyOf(value, size);
    }
 public String(char value[], int offset, int count) {
        if (offset < 0) {
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count < 0) {
            throw new StringIndexOutOfBoundsException(count);
        }
        // Note: offset or count might be near -1>>>1.
        if (offset > value.length - count) {
            throw new StringIndexOutOfBoundsException(offset + count);
        }
        this.offset = 0;
        this.count = count;
        this.value = Arrays.copyOfRange(value, offset, offset+count);
    }
....

以上是String源码中的内容,可以看到有很多的构造方法

String不变性,是指String对象一旦生成,就不能对它进行修改,即这个对象的状态在对象创建时就固定不变了,相当于不变模式(当一个对象被多线程共享时,并且频繁访问,可以省略同步和锁等待时间)。

String对常量池(字符串池)的优化

String s = "1";
s = s+"2";
s = s+"3";
以上这段代码,编译后,我们可以反编译看看编译后的代码是什么样子的
public static void main(String args[])
{
String s = "1";
s = (new StringBuilder()).append(s).append("2").toString();
s = (new StringBuilder()).append(s).append("3").toString();
}
以上因为编译期,不能得出最终的s是什么样子的,所以内部使用了StringBuilder优化
String s = "1"+"2"+"3";
-->
String s = "123";
在编译期知道s是什么样子的,所以直接优化
在常量池中,当两个String对象拥有相同的值时,它们引用常量池中的同一个拷贝,当同一个字符串反复出现时,可以节省大量内存空间
String str1="123";
String str2="123";
String str3=new String("123");
str1和str2是指向同一块内存地址空间,而str3则是另一块内存地址空间,但是最终都指向常量池中的同一个“123”字符串

使用indexOf()和substring()代替split(),效率更高

使用charAt()代替startsWith(),endsWith(),效率更高

public static Object[] mySplit(String source,String s) {
		List<String> list = new ArrayList<String>();
		int loc=source.indexOf(s),length=source.length();
		String temp = "";
		while(loc!=-1) {
			temp = source.substring(0, loc);
			list.add(temp);
			source=source.substring(loc+1, length);
			loc = source.indexOf(s);
			length=source.length();
		}
		return list.toArray();
	}

public static void main(String args[]) {
		String str = "KJDKGF-sdfgdssdfb-5241354651";
		int count = 10000000;
		String temp = "";
		long begin = System.currentTimeMillis();
		for(int i=0;i<count;i++) {
			temp = str.split("-")[0];
		}
		System.out.println(System.currentTimeMillis()-begin);
		begin = System.currentTimeMillis();
		for(int i=0;i<count;i++) {
			temp = str.substring(0,str.indexOf("-"));
		}
		System.out.println(System.currentTimeMillis()-begin);
	}

10000000次操作,从以下结果可以很明显的看出来的性能的差异,在计算机的世界里1ns都应该珍惜啊

1365
129

相差10倍的性能

你可能感兴趣的:(String,无所不在的数据类型)