緩存實例的不可變類:

一、不可變類的實例狀態不可改變,能夠被多個對象很方便的共享java

二、若是程序常常使用某個不可變類的實例,那麼把該實例保存近緩存是一個好的選擇,不用每次都生成新的實例對象,消耗系統開銷數組

以下代碼實例:將建立的不可變類實例進行緩存緩存

import static java.lang.System.*;
import java.util.Arrays;
class CacheImmutable{
	//-定義緩存數組的長度,私有的,靜態的,不可更改的
	private static final int MAX_SIZE=3;
	//-定義緩存數組,來緩存已有的實例,靜態的,不可更改的,不變類的要素之一
	private static final CacheImmutable[] cache = new CacheImmutable[MAX_SIZE];
	//-記錄緩存實例在緩存中的位置,cache[pos-1]是最新緩存進來的實例
	private static int pos=0;
	//-記錄當前實例的name,不可更改的,每一個實例的name都不一樣,因此不能是static修飾
	private final String name;
	
	//-獲取當前實例的name,只設置獲取getter方法,不設置設置setter方法,不變類的要素之一
	public String getName(){
		return this.name;
	}

	//-帶參數的構造器,name賦值的惟一路徑,private修飾,不能外部new新的實例,不變類的要素之一
	private CacheImmutable(String name){
		this.name=name;
	}

	//-獲取類實例對象的惟一方式
	public static CacheImmutable valueOf(String name){
		
		//-循環緩存數組,判斷新定義的實例對象是否已經存在,如存在,直接返回已有的實例,再也不存入新的實例
		for(int i=0;i<MAX_SIZE;i++){
			if(cache[i]!=null&&cache[i].getName().equals(name)){
				return cache[i];
			}
		}

		//-若是緩存數組已經存滿,新的實例覆蓋第一個舊實例,並把位置標爲 1,若是緩存沒滿,保存進緩存,位標+1,並返回該實例
		if(pos==MAX_SIZE){
			cache[0] = new CacheImmutable(name);
			pos=1;
		}else{
			cache[pos++] = new CacheImmutable(name);
		}
		
		return cache[pos-1];
	}

	//-重寫Object類的equals()方法
	public boolean equals(Object obj){
		if(this==obj){
			return true;
		}
		if(obj!=null&&obj.getClass()==CacheImmutable.class){
			CacheImmutable ci = (CacheImmutable)obj;
			if(this.getName().equals(ci.getName())){
				return true;
			}
		}
		return false;
	}

	//-重寫Object類的hashCode()方法
	public int hashCode(){
		return name.hashCode();
	}

	//-獲取當前實例在緩存中是第幾個
	public int getPos(){
		return pos;
	}
	
	//-獲取整個緩存數組
	public CacheImmutable[] getArray(){
		return cache;
	}
}

public class CacheImmutableTest{
	public static void main(String[] args){
		
		//-定義一個 CacheImmutable類實例:cache1,name爲:ImmutableClass,並保存進緩存
		CacheImmutable cache1 = CacheImmutable.valueOf("ImmutableClass");
		//-輸出當前實例在緩存中的位置
		out.println(cache1.getPos());
		//-遍歷整個緩存,輸出緩存中每一個實例的name值
		for(int i=0;i<cache1.getPos();i++){
			out.println(cache1.getArray()[i].getName());
			
		}
		//-輸出整個緩存數組
		out.println(Arrays.toString(cache1.getArray()));
		out.println();		

		//-新定義的實例:cache2 與 已經保存進緩存的實例:cache1的name值相等,因此視爲已存在實例,不會再次進緩存
		CacheImmutable cache2 = CacheImmutable.valueOf("ImmutableClass");
		out.println(cache2.getPos());
		for(int i=0;i<cache2.getPos();i++){
			out.println(cache2.getArray()[i].getName());
			
		}
		out.println(Arrays.toString(cache2.getArray()));
		out.println();	
		
		CacheImmutable cache3 = CacheImmutable.valueOf("ImmutableClass_a");
		out.println(cache3.getPos());
		for(int i=0;i<cache3.getPos();i++){
			out.println(cache3.getArray()[i].getName());
			
		}
		out.println(Arrays.toString(cache3.getArray()));
		out.println();	
		
		CacheImmutable cache4 = CacheImmutable.valueOf("ImmutableClass_b");
		out.println(cache4.getPos());
		for(int i=0;i<cache4.getPos();i++){
			out.println(cache4.getArray()[i].getName());
			
		}
		out.println(Arrays.toString(cache4.getArray()));
		out.println();	
		
		out.println(cache1.equals(cache2));
		out.println(cache1.equals(cache3));
		out.println();	

		//-新定義的實例:cache5,會覆蓋緩存數組中的第一個實例(由於緩存已滿),
		CacheImmutable cache5 = CacheImmutable.valueOf("ImmutableClass_c");
		out.println(cache5.getPos());
		for(int i=0;i<cache5.getPos();i++){
			out.println(cache5.getArray()[i].getName());
			
		}
		out.println(Arrays.toString(cache5.getArray()));
	}	
}

 運行效果:性能

 總結:this

一、是否須要隱藏類的構造器,徹底取決於系統需求對象

二、盲目亂用緩存可能致使系統性能降低blog

三、緩存的對象會佔用內存,若是對象只用一次,重複使用的機率不大,緩存該實例就弊大於利內存

四、若是某個對象須要頻繁的調用,緩存該實例就利大於弊ci

 

Java提供的Integer類,就採用了上面CacheImmutable類相同的緩存策略:get

一、若是採用 new 構造器來建立 Integer 對象,返回的是全新的 Integer 對象

二、若是採用 valueOf() 方法來建立 Integer 對象,則在建立該對象的同時,會緩存該方法建立的對象

三、Integer 只緩存 -128-127之間的 Integer 對象,超過該範圍的對象不會緩存

以下代碼示例:

public class IntegerCache{
	public static void main(String[] args){
		//-生成新的Integer對象實例:a
		Integer a = new Integer(5);
		
		//-生成新的Integer對象實例:b,並緩存
		Integer b = Integer.valueOf(5);
		//-直接從緩存裏獲取對象,由於緩存裏相同對象已經存在
		Integer c = Integer.valueOf(5);
		
		//-false
		System.out.println(a==b);
		//-true
		System.out.println(b==c);
		
		//-Integer只緩存-128-127之間的值,200對應的Integer對象沒有被緩存
		Integer d = Integer.valueOf(200);
		Integer e = Integer.valueOf(200);

		//-由於沒緩存,因此是兩個不一樣的對象,返回false
		System.out.println(d==e);
	}
}

 運行結果:

相關文章
相關標籤/搜索