Java_String
1.==与equals
1)a==b是进行地址比较,a.equals(b)是进行值比较。
2)String类是final不可变类,对String的改变都会引发新的String对象的生成。
3)“abc”形式会分配到字符串常量池。
4)JVM对于字符串常量的"+"号连接,编译期就将常量字符串的"+"连接优化为连接后的值。
5)如果在字符串+操作过程中,有引用存在,如t="a"; b = t+"bc";中的t,则运行期才能获得t内存块,显然不会优化为"abc"常量。但在变量前加个final,也会在编译期存储为常量池中或嵌入到它的字节码流中。
2.用String拼接与StringBuilder拼接
3.String、StringBuilder、StringBuffer
当运算量不是很高时,可以不用考虑性能问题;
单线程时,当运算量百万级别时,选StringBuilder;
多线程时,当运算量百万级别时,选StringBuffer;
package day_3.String; public class TestString { static void test_1(){ int i=0; while (true) { String a = "abc"; //String a = new String("abc"); try { Thread.sleep(10); System.out.println(i++); } catch (InterruptedException e) { e.printStackTrace(); } a = null; } } /** * 1)a==b是进行地址比较,a.equals(b)是进行值比较。 2)String类是final不可变类,对String的改变都会引发新的String对象的生成。 3)“abc”形式会分配到字符串常量池。 */ static void test_2(){ // String a = "abc"; // String b = "abc"; // System.out.println("a==b : " + (a==b)); //true // System.out.println("a.equals(b) : " + a.equals(b) ); //true // String a = new String("abc"); // String b = new String("abc"); // System.out.println("a==b : " + (a==b)); //false // System.out.println("a.equals(b) : " + a.equals(b) ); //true String a = "abc"; String b = new String("abc"); System.out.println("a==b : " + (a==b)); //false System.out.println("a.equals(b) : " + a.equals(b) ); //true } /** * 4)JVM对于字符串常量的"+"号连接,编译期就将常量字符串的"+"连接优化为连接后的值。 * 5)如果在字符串+操作过程中,有引用存在,如t="a"; b = t+"bc";中的t,则运行期才能获得 t内存块,显然不会优化为"abc"常量。但在变量前加个final,也会在编译期存储为常量池中或嵌入 到它的字节码流中。 */ static void test_3(){ String a = "abc"; String b = "a"+"bc"; System.out.println("a==b : " + (a==b)); //true System.out.println("a.equals(b) : " + a.equals(b) ); //true // String a = "abc"; // String t = "a"; // String b = t+"bc"; // System.out.println("a==b : " + (a==b)); //false // System.out.println("a.equals(b) : " + a.equals(b) ); //true // String a = "abc"; // final String t="a"; // String b = t+"bc"; // System.out.println("a==b : " + (a==b)); //true // System.out.println("a.equals(b) : " + a.equals(b) ); //true } static void test_4(){ String str="1234567890上海"; int len = str.length(); System.out.println("len = " + len); String str2 = "Hello," + " java" + "! " + len; System.out.println("str2 = " + str2); } /** * String、StringBuilder 1) String所引用空间扔掉,开辟新空间来存放字串(不变类),会出现内存碎片; 2) StringBuilder先开辟了缓冲区,append()在缓冲区中操作,内存效率大大提高(可变类)。 */ static void test_5(){ System.out.println("运行前可用内存" + Runtime.getRuntime().freeMemory()); String s = ""; String newStr = new String("abc"); StringBuilder builder = new StringBuilder(1000); for (int i = 0; i < 100; i++) { // s = s + newStr; //可用内存保持下降 builder.append(newStr); //可用内存保持不变 if (i % 10 == 0) { System.out.println("运行中可用内存" + Runtime.getRuntime().freeMemory()); } } } /** * StringBuilder、StringBuffer 1) 相似点:做字符串连接时,都不会产生内存碎片; 2) 差别:StringBuilder类不是线程安全的,但其在单线程中的性能比StringBuffer高。 */ static void test_6(){ StringBuilder strBuilder = new StringBuilder(); String str = new String(); StringBuffer strBuffer = new StringBuffer(); System.out.println( System.currentTimeMillis()); for (int i = 0; i < 1000000; i++) { // str = str + " add "; // strBuilder = strBuilder.append(" add "); strBuffer = strBuffer.append(" add "); } System.out.println( System.currentTimeMillis()); } public static void main(String[] args) { test_6(); } }