关于对String中intern方法的理解

在java的String中有个一直被我们忽视了的方法intern方法:
它的官方解释是:
一个初始时为空的字符串池,它由类 String 私有地维护。 当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。

这里其实就是从堆中把栈的引用指向了常量池中,减少了重复的字符占空间!牺牲的速度不是一点半点的(几乎比equals方法慢了一倍多),但是intern对内存的优化也是很大的,试想所有重复的字符都被存入了常量池中,系统越复杂,体现出来的优化就越明显!

使用intern还是equals还是要结合场景,要速度就要牺牲空间,要空间就要牺牲速度!

对String的intern和equals的速度差异测试:

package test;

import java.util.Random;

/**
 * @author mzy
 * 
 */
public class Test2 {
	public static void main(String[] args) {
		/*
		String s = new String("str");
		String s1 = "str";
		System.out.println(s == s1);
		
		s = s.intern();
		// s1 = s1.intern();
		System.out.println(s == s1);
		*/
		
		/*
		String s = new String("1");  
		s = s.intern();  
		String s2 = "1";  
		System.out.println(s == s2);  
		  
		String s3 = new String("1") + new String("1");  
		s3.intern();  
		String s4 = "11";  
		System.out.println(s3 == s4);  
		*/
		
		/*
		String s1 = "mzy";
		String s2 = new String("mzy");
		System.out.println(s1.intern() == s2.intern());
		*/
		
		/*
		String s1 = "mzy";
		System.out.println(s1.intern() == new Test2().getString().intern());
		*/
		
		String[] strs = new String[1000];
		String s1 = "";
		String s2 = "";
		int tmp = 97;
		
		long t = System.currentTimeMillis();
		
		Random random = new Random(System.currentTimeMillis());
		for(int i=0; i<10000; i++) {
			for(int j=0; j<5; j++) {
				s1 += (char)(tmp += random.nextInt(26));
				s2 += (char)(tmp += random.nextInt(26));
			}
			// if(s1.equals(s2)) {} // 1366ms
			if(s1.intern() == s2.intern()) {} // 2908ms
		}
		System.out.println((System.currentTimeMillis()-t)+"ms");
		
	}
}


posted @ 2018-05-14 22:57  五彩世界  阅读(249)  评论(0编辑  收藏  举报