zoukankan      html  css  js  c++  java
  • 缓存实例的不可变类:

    1、不可变类的实例状态不可改变,可以被多个对象很方便的共享

    2、如果程序经常使用某个不可变类的实例,那么把该实例保存近缓存是一个好的选择,不用每次都生成新的实例对象,消耗系统开销

    如下代码实例:将创建的不可变类实例进行缓存

    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()));
    	}	
    }
    

     运行效果:

     总结:

    1、是否需要隐藏类的构造器,完全取决于系统需求

    2、盲目乱用缓存可能导致系统性能下降

    3、缓存的对象会占用内存,如果对象只用一次,重复使用的概率不大,缓存该实例就弊大于利

    4、如果某个对象需要频繁的调用,缓存该实例就利大于弊

    Java提供的Integer类,就采用了上面CacheImmutable类相同的缓存策略:

    1、如果采用 new 构造器来创建 Integer 对象,返回的是全新的 Integer 对象

    2、如果采用 valueOf() 方法来创建 Integer 对象,则在创建该对象的同时,会缓存该方法创建的对象

    3、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);
    	}
    }
    

     运行结果:

  • 相关阅读:
    BINARY and varBINARY
    DECIMAL Data Type
    timestamp ---自动更新修改时间 与 记录首次插入时间
    可视化之Berkeley Earth
    可视化之Earth NullSchool
    数据可视化之风向图
    “System.Runtime.InteropServices.COMException”类型的第一次机会异常在 ESRI.ArcGIS.Version.dll 中发生
    如何用arcgis进行WGS84的投影坐标变换
    break和continue的区别
    MySql查询系统时间,SQLServer查询系统时间,Oracle查询系统时间
  • 原文地址:https://www.cnblogs.com/baby-zhude/p/8098952.html
Copyright © 2011-2022 走看看