kotlin版對象復(fù)用池

項(xiàng)目中經(jīng)常用到對象池復(fù)用布朦,但是不一樣的對象對應(yīng)的復(fù)用池都不統(tǒng)一腿倚。想著能否有一個(gè)對象池纯出,可以不用關(guān)心對象是啥,實(shí)現(xiàn)對象池的功能敷燎?
對象池的功能需要支持:

  1. 不關(guān)系對象是什么暂筝,都能復(fù)用。
  2. 如何生產(chǎn)對象硬贯?
  3. 如何回收對象焕襟?

對于問題點(diǎn) 1 可以借助泛型和集合來實(shí)現(xiàn)。本來想?yún)⒖糓essage來實(shí)現(xiàn)饭豹,但是沒法給對象動態(tài)添加一個(gè)next屬性鸵赖,因此用一個(gè)集合來保存
對于問題點(diǎn) 2,如果我們復(fù)用集合里面有拄衰,直接返回集合里面的它褪,如果沒有,我們要實(shí)現(xiàn)化一個(gè)對象返回翘悉,但是有不知道他是什么類型茫打,首先想到的是傳個(gè)Class進(jìn)來,這樣我們就可以反射實(shí)例化一個(gè)對象
對于問題點(diǎn)3,所謂回收對象老赤,就是把對象的屬性都賦默默認(rèn)值轮洋,然后把該對象存入集合。對象屬性賦默認(rèn)值也可以反射實(shí)現(xiàn)

對于第二點(diǎn)反射實(shí)例化一個(gè)對象抬旺,因?yàn)閷ο罂赡苡卸鄠€(gè)構(gòu)造器弊予。而我們又不知道調(diào)用者到底要實(shí)例化哪一個(gè),因此從所有構(gòu)造器中選第一個(gè)實(shí)例化开财。為了給調(diào)用靈活性块促,這里我們添加一個(gè)factory給調(diào)用者自己決定是否要實(shí)例化一個(gè)對象。如果調(diào)用者自己創(chuàng)建了床未,就直接返回
上代碼

class AnyPool<T>(private val clazz: Class<T>) {
    companion object{
      //方便調(diào)用者生成一個(gè)AnyPool對象
       inline fun <reified T> getAnyPool():AnyPool<T>{
            return AnyPool(T::class.java)
        }
    }
    //復(fù)用池
    private val nodes = mutableListOf<T>()
    //從復(fù)用池拿竭翠,如果復(fù)用池沒有,先從factory創(chuàng)建薇搁,如果factory沒有斋扰,則反射生成一個(gè)
    fun getFromPool(factory: () -> T? = { null }): T {
        if (nodes.isEmpty()) {
            println("from create")
            return factory() ?: let {
                val constructor = clazz.constructors[0]
                val parameters = constructor.parameters
                val params = arrayOfNulls<Any?>(parameters.size)
                parameters.forEachIndexed { index, parameter ->
                    params[index] = parameter.type.getDefault()
                }
                constructor.newInstance(*params) as T
            }


        }
        println("form pool")
        return nodes.removeAt(0)
    }
    //回收該對象到復(fù)用池
    fun recycle(node:T){
        node.clearField()
        nodes+=node
    }
    private  fun <K> Class<K>.getDefault():K?{
        return when(this){
             Int::class.java->0 as K
            Boolean::class.java->false as K
            Float::class.java->0f as K
            Double::class.java->0.0 as K
            Long::class.java->0L as K
            Short::class.java->0 as K
            Char::class.java->'0' as K
            Byte::class.java->0 as K
            else -> null
        }
    }
  //將該對象屬性賦默認(rèn)值
    private fun T.clearField(){
        (clazz.declaredFields+clazz.fields).forEach {field->
            field.isAccessible = true
            field.set(this,field.type.getDefault())
        }
    }

}

測試代碼

data class Bean (var age:Int,var name:String?,var bean: Bean?)
fun testAnyPool(){
        val anyPool = AnyPool.getAnyPool<Bean>()
        val list = mutableListOf<Bean>()
        val test = Bean(11,"222",null)
       for (i in 0..4){
            val  bean = when {
               i%2==0-> anyPool.getFromPool {
                    Bean(i, "我是工廠創(chuàng)建的", test)
                }
                else ->{
                    anyPool.getFromPool()
                }
            }
            bean.age = i
            bean.bean = test
            list+=bean
            println(bean)
        }
        list.forEach {
            anyPool.recycle(it)
        }
        for (i in 1..5){
            println(anyPool.getFromPool())
        }
    }

輸出,可以看到很好的滿足了對象池的功能

from create
Bean(age=0, name=我是工廠創(chuàng)建的, bean=Bean(age=11, name=222, bean=null))
from create
Bean(age=1, name=null, bean=Bean(age=11, name=222, bean=null))
from create
Bean(age=2, name=我是工廠創(chuàng)建的, bean=Bean(age=11, name=222, bean=null))
from create
Bean(age=3, name=null, bean=Bean(age=11, name=222, bean=null))
from create
Bean(age=4, name=我是工廠創(chuàng)建的, bean=Bean(age=11, name=222, bean=null))
form pool
Bean(age=0, name=null, bean=null)
form pool
Bean(age=0, name=null, bean=null)
form pool
Bean(age=0, name=null, bean=null)
form pool
Bean(age=0, name=null, bean=null)
form pool
Bean(age=0, name=null, bean=null)

Process finished with exit code 0

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末啃洋,一起剝皮案震驚了整個(gè)濱河市传货,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌宏娄,老刑警劉巖问裕,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異孵坚,居然都是意外死亡粮宛,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門卖宠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來巍杈,“玉大人,你說我怎么就攤上這事扛伍】昶瑁” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵刺洒,是天一觀的道長鳖宾。 經(jīng)常有香客問我,道長逆航,這世上最難降的妖魔是什么鼎文? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮纸泡,結(jié)果婚禮上漂问,老公的妹妹穿的比我還像新娘赖瞒。我一直安慰自己,他們只是感情好蚤假,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布栏饮。 她就那樣靜靜地躺著,像睡著了一般磷仰。 火紅的嫁衣襯著肌膚如雪袍嬉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天灶平,我揣著相機(jī)與錄音伺通,去河邊找鬼。 笑死逢享,一個(gè)胖子當(dāng)著我的面吹牛罐监,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瞒爬,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼弓柱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了侧但?” 一聲冷哼從身側(cè)響起矢空,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎禀横,沒想到半個(gè)月后屁药,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡柏锄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年酿箭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绢彤。...
    茶點(diǎn)故事閱讀 39,834評論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡七问,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出茫舶,到底是詐尸還是另有隱情,我是刑警寧澤刹淌,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布饶氏,位于F島的核電站,受9級特大地震影響有勾,放射性物質(zhì)發(fā)生泄漏疹启。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一蔼卡、第九天 我趴在偏房一處隱蔽的房頂上張望喊崖。 院中可真熱鬧,春花似錦、人聲如沸荤懂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽节仿。三九已至晤锥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間廊宪,已是汗流浹背矾瘾。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留箭启,地道東北人壕翩。 一個(gè)月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像傅寡,于是被迫代替她去往敵國和親戈泼。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容