缓存实例的不可变类

来源:互联网 发布:js获取图片原始尺寸 编辑:程序博客网 时间:2024/05/20 11:47

不可变类的大致意思:创建该类的实例后,该实例的Field是不可改变的。比如Java提供的8个包装类和String类都是不可变类。

自定义不可变类的基本步骤:

1使用private和final修饰符来修饰该类的Field。

2提供带参数构造器,来初始化类里的Field。

3仅为该类的Field提供getter方法,不要为该类Field提供setter方法。

4如果有必要,重写Object类的hashCode和equals方法,equals方法以关键Field来作为判断两个对象是否相等的标准。

设计不可变类的好处在于它被多个对象共享时,该类的Field不用担心被某个对象改变。当程序需要经常使用多个相同的不可变类实例时,那么可以用缓存来满足这种需求,这样可以减少系统内存的开销。Java中用不少的类是用到缓存实例的不可变类来返回相同的实例。如:

Integer t1=Integer.valueOf(5);Integer t2=Integer.valueOf(5);System.out.println(t1==t2) 那输出的结果会是true还是false呢?

上面的结果输出是true.那么它的原理是如何实现的呢?接下来笔者去模仿它的原理实现:

public class MyInteger{//设置缓存多少个实例private static int MAX_SIZE=10; //用该数组来缓存实例private static MyInteger[] cache=new MyInteger[MAX_SIZE];//记录缓存实例在缓存中的位置,cache[position-1]是最新缓存的实例private static int position=0;//不可变类的Fieldprivate final Integer  number;public MyInteger(Integer number){this.number = number;}public Integer getNumber(){return number;}public static MyInteger valueOf(Integer number){for(int i=0;i<MAX_SIZE;i++){if(cache[i]!=null&&cache[i].getNumber()==number){return cache[i];}} //如果缓存已满,则最新实例覆盖第一个实例if(position==MAX_SIZE){cache[0]=new MyInteger(number);position=1;}//缓存未满else{cache[position++]=new MyInteger(number);}//返回最新实例return cache[position-1];} //重写该方法判断是否是同一个对象@Overridepublic boolean equals(Object obj){if(this==obj){return true;}if(obj!=null&&obj instanceof MyInteger){MyInteger other=(MyInteger)obj;return this.number==other.number;}return false;}@Overridepublic int hashCode(){return number.hashCode();}}

测试部分:

MyInteger t1=MyInteger.valueOf(5);MyInteger t2=MyInteger.valueOf(5);MyInteger t3=MyInteger.valueOf(6);MyInteger t4=new MyInteger(5);System.out.println(t1==t2);System.out.println(t1==t3);System.out.println(t1==t4);truefalsefalse

上面就是笔者模仿如何缓存Integer实例的不可变类。这只是其中一种的缓存设计方法之一,缓存的实现方式有很多种,大家可以去谷歌或百度老人那里看一下。

各位学者可以去点击下面的链接用类似缓存设计不可变类去模仿类似String.valueOf(String name)的实现,该题目能自动批判。

题目链接

题目答案:

public class MYString extends Super{//设置缓存多少个实例private static int MAX_SIZE=10; //用该数组来缓存实例private static MYString[] cache=new MYString[MAX_SIZE];//记录缓存实例在缓存中的位置,cache[position-1]是最新缓存的实例private static int position=0;    public MYString(String name){super(name);}public static MYString valueOf(String name){for(int i=0;i<MAX_SIZE;i++){if(cache[i]!=null&&cache[i].getName().endsWith(name)){return cache[i];}} //如果缓存已满,则最新实例覆盖第一个实例if(position==MAX_SIZE){cache[0]=new MYString(name);position=1;}//缓存未满else{cache[position++]=new MYString(name);}//返回最新实例return cache[position-1];} //重写该方法判断是否是同一个对象@Overridepublic boolean equals(Object obj){if(this==obj){return true;}if(obj!=null&&obj instanceof MYString){MYString other=(MYString)obj;return this.getName().equals(other.getName());}return false;}@Overridepublic int hashCode(){return getName().hashCode();}}

如果描述有错误和题目或答案有问题可以在下面的帖子留言,笔者将会非常感谢的指正。


0 0