/* Ċ Ġ* ĠCopyright Ġ 2 0 1 8 ĠThe ĠAndroid ĠOpen ĠSource ĠProject Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ package Ġlife tracker . feature . record Ċ Ċ import Ġandroid . os . Handler Ċ import Ġandroid . os . Looper Ċ import Ġandroidx . recyclerview . widget .* Ċ import Ġandroidx . recyclerview . widget . Diff Util . Diff Result Ċ import Ġjava . util .* Ċ import Ġjava . util . concurrent . Copy On Write ArrayList Ċ import Ġjava . util . concurrent . Executor Ċ Ċ /** Ċ Ġ* ĠHelper Ġfor Ġcomputing Ġthe Ġdifference Ġbetween Ġtwo Ġlists Ġvia Ġ[ Diff Util ] Ġon Ġa Ġbackground Ċ Ġ* Ġthread . Ċ Ġ* Ċ Ġ* Ċ Ġ* ĠIt Ġcan Ġbe Ġconnected Ġto Ġa Ċ Ġ* Ġ[ RecyclerView . Adapter ], Ġand Ġwill Ġsignal Ġthe Ċ Ġ* Ġadapter Ġof Ġchanges Ġbetween Ġsum bit ted Ġlists . Ċ Ġ* Ċ Ġ* Ċ Ġ* ĠFor Ġsimplicity , Ġthe Ġ[ ListAdapter ] Ġwrapper Ġclass Ġcan Ġoften Ġbe Ġused Ġinstead Ġof Ġthe Ċ Ġ* ĠAsync List Differ Ġdirectly . ĠThis ĠAsync List Differ Ġcan Ġbe Ġused Ġfor Ġcomplex Ġcases , Ġwhere Ġoverriding Ġan Ċ Ġ* Ġadapter Ġbase Ġclass Ġto Ġsupport Ġasynchronous ĠList Ġdiff ing Ġisn 't Ġconvenient . Ċ Ġ* Ċ Ġ* Ċ Ġ* ĠThe ĠAsync List Differ Ġcan Ġconsume Ġthe Ġvalues Ġfrom Ġa ĠLive Data Ġof Ġ` List ` Ġand Ġpresent Ġthe Ċ Ġ* Ġdata Ġsimply Ġfor Ġan Ġadapter . ĠIt Ġcomputes Ġdifferences Ġin Ġlist Ġcontents Ġvia Ġ[ Diff Util ] Ġon Ġa Ċ Ġ* Ġbackground Ġthread Ġas Ġnew Ġ` List ` s Ġare Ġreceived . Ċ Ġ* Ċ Ġ* Ċ Ġ* ĠUse Ġ[. getCurrent List ] Ġto Ġaccess Ġthe Ġcurrent ĠList , Ġand Ġpresent Ġits Ġdata Ġobjects . ĠDiff Ċ Ġ* Ġresults Ġwill Ġbe Ġdis patched Ġto Ġthe ĠList Update Callback Ġimmediately Ġbefore Ġthe Ġcurrent Ġlist Ġis Ċ Ġ* Ġupdated . ĠIf Ġyou 're Ġdispatch ing Ġlist Ġupdates Ġdirectly Ġto Ġan ĠAdapter , Ġthis Ġmeans Ġthe ĠAdapter Ġcan Ċ Ġ* Ġsafely Ġaccess Ġlist Ġitems Ġand Ġtotal Ġsize Ġvia Ġ[. getCurrent List ]. Ċ Ġ* Ċ Ġ* Ċ Ġ* ĠA Ġcomplete Ġusage Ġpattern Ġwith ĠRoom Ġwould Ġlook Ġlike Ġthis : Ċ Ġ* Ġ< pre > Ċ Ġ* Ġ@ Dao Ċ Ġ* Ġinterface ĠUser Dao Ġ{ Ċ Ġ* Ġ@ Query (" SELECT Ġ* ĠFROM Ġuser ĠORDER ĠBY ĠlastName ĠASC ") Ċ Ġ* Ġpublic Ġabstract ĠLive Data & lt ; List & lt ; User >> Ġusers By LastName (); Ċ Ġ* Ġ} Ċ Ġ* Ċ Ġ* Ġclass ĠMy ViewModel Ġextends ĠViewModel Ġ{ Ċ Ġ* Ġpublic Ġfinal ĠLive Data & lt ; List & lt ; User >> Ġusers List ; Ċ Ġ* Ġpublic ĠMy ViewModel ( User Dao Ġuser Dao ) Ġ{ Ċ Ġ* Ġusers List Ġ= Ġuser Dao . users By LastName (); Ċ Ġ* Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ċ Ġ* Ġclass ĠMy Activity Ġextends ĠAppCompatActivity Ġ{ Ċ Ġ* Ġ@ Override Ċ Ġ* Ġpublic Ġvoid ĠonCreate ( Bundle Ġsaved State ) Ġ{ Ċ Ġ* Ġsuper . onCreate ( saved State ); Ċ Ġ* ĠMy ViewModel ĠviewModel Ġ= Ġnew ĠViewModel Provider ( this ). get ( My ViewModel . class ); Ċ Ġ* ĠRecyclerView Ġre cyclerView Ġ= ĠfindViewById ( R . id . user _ list ); Ċ Ġ* ĠUser Adapter Ġadapter Ġ= Ġnew ĠUser Adapter (); Ċ Ġ* ĠviewModel . users List . observe ( this , Ġlist Ġ-> Ġadapter . submit List ( list )); Ċ Ġ* Ġre cyclerView . setAdapter ( adapter ); Ċ Ġ* Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ċ Ġ* Ġclass ĠUser Adapter Ġextends ĠRecyclerView . Adapter & lt ; User ViewHolder > Ġ{ Ċ Ġ* Ġprivate Ġfinal ĠAsync List Differ & lt ; User > Ġm Differ Ġ= Ġnew ĠAsync List Differ ( this , ĠDIFF _ CALLBACK ); Ċ Ġ* Ġ@ Override Ċ Ġ* Ġpublic Ġint ĠgetItem Count () Ġ{ Ċ Ġ* Ġreturn Ġm Differ . getCurrent List (). size (); Ċ Ġ* Ġ} Ċ Ġ* Ġpublic Ġvoid Ġsubmit List ( List & lt ; User > Ġlist ) Ġ{ Ċ Ġ* Ġm Differ . submit List ( list ); Ċ Ġ* Ġ} Ċ Ġ* Ġ@ Override Ċ Ġ* Ġpublic Ġvoid Ġon Bind ViewHolder ( User ViewHolder Ġholder , Ġint Ġposition ) Ġ{ Ċ Ġ* ĠUser Ġuser Ġ= Ġm Differ . getCurrent List (). get ( position ); Ċ Ġ* Ġholder . bind To ( user ); Ċ Ġ* Ġ} Ċ Ġ* Ġpublic Ġstatic Ġfinal ĠDiff Util . Item Callback & lt ; User > ĠDIFF _ CALLBACK Ċ Ġ* Ġ= Ġnew ĠDiff Util . Item Callback & lt ; User >() Ġ{ Ċ Ġ* Ġ@ Override Ċ Ġ* Ġpublic Ġboolean Ġare Items The Same ( Ċ Ġ* Ġ@ NonNull ĠUser Ġold User , Ġ@ NonNull ĠUser Ġnew User ) Ġ{ Ċ Ġ* Ġ// ĠUser Ġproperties Ġmay Ġhave Ġchanged Ġif Ġre loaded Ġfrom Ġthe ĠDB , Ġbut ĠID Ġis Ġfixed Ċ Ġ* Ġreturn Ġold User . getId () Ġ== Ġnew User . getId (); Ċ Ġ* Ġ} Ċ Ġ* Ġ@ Override Ċ Ġ* Ġpublic Ġboolean Ġare Contents The Same ( Ċ Ġ* Ġ@ NonNull ĠUser Ġold User , Ġ@ NonNull ĠUser Ġnew User ) Ġ{ Ċ Ġ* Ġ// ĠNOTE : Ġif Ġyou Ġuse Ġequals , Ġyour Ġobject Ġmust Ġproperly Ġoverride ĠObject # equals () Ċ Ġ* Ġ// ĠInc orrect ly Ġreturning Ġfalse Ġhere Ġwill Ġresult Ġin Ġtoo Ġmany Ġanimations . Ċ Ġ* Ġreturn Ġold User . equals ( new User ); Ċ Ġ* Ġ} Ċ Ġ* Ġ} Ċ Ġ* Ġ}</ pre > Ċ Ġ* Ċ Ġ* Ġ@ param Ġ< T > ĠType Ġof Ġthe Ġlists Ġthis ĠAsync List Differ Ġwill Ġreceive . Ċ Ġ* Ċ Ġ* Ġ@ see ĠDiff Util Ċ Ġ* Ċ Ġ* Ġ@ see ĠAdapter List Update Callback Ċ </ T > Ġ*/ Ċ class ĠAsync List Differ Without Moves < T >( ĊĠĠĠ Ġprivate Ġval Ġm Update Callback : ĠList Update Callback , ĊĠĠĠ Ġ/* Ġsynthetic Ġaccess Ġ*/ val Ġm Config : ĠAsync Differ Config < T > Ċ ) Ġ{ ĊĠĠĠ Ġvar Ġm MainThread Executor : ĠExecutor ĊĊĠĠĠ Ġprivate Ġclass ĠMain Thread Executor Ġinternal Ġconstructor () Ġ: ĠExecutor Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġm Handler Ġ= ĠHandler ( Looper . get Main Looper ()) ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġexecute ( command : ĠRunnable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Handler . post ( command ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠListener Ġfor Ġwhen Ġthe Ġcurrent ĠList Ġis Ġupdated . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġ< T > ĠType Ġof Ġitems Ġin ĠList ĊĠĠĠ Ġ</ T > Ġ*/ ĊĠĠĠ Ġinterface ĠList Listener < T > Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠCalled Ġafter Ġthe Ġcurrent ĠList Ġhas Ġbeen Ġupdated . ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġprevious List ĠThe Ġprevious Ġlist . ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġcurrent List ĠThe Ġnew Ġcurrent Ġlist . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġon Current List Changed ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprevious List : ĠList < T >, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent List : ĠList < T > ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġm Listeners : ĠMutable List < List Listener < T >> Ġ= ĊĠĠĠĠĠĠĠ ĠCopy On Write ArrayList () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠConvenience Ġfor ĊĠĠĠĠ Ġ* Ġ` Async List Differ ( new ĠAdapter List Update Callback ( adapter ), ĊĠĠĠĠ Ġ* Ġnew ĠAsync Differ Config . Builder (). set Diff Callback ( diff Callback ). build ()); ` ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġadapter ĠAdapter Ġto Ġdispatch Ġposition Ġupdates Ġto . ĊĠĠĠĠ Ġ* Ġ@ param Ġdiff Callback ĠItem Callback Ġthat Ġcomp ares Ġitems Ġto Ġdispatch Ġappropriate Ġanimations Ġwhen ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ see ĠDiff Util . Diff Result . dispatch Updates To ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġconstructor ( ĊĠĠĠĠĠĠĠ Ġadapter : ĠRecyclerView . Adapter <* >, ĊĠĠĠĠĠĠĠ Ġdiff Callback : ĠDiff Util . Item Callback < T > ĊĠĠĠ Ġ) Ġ: Ġthis ( ĊĠĠĠĠĠĠĠ ĠAdapter List Update Callback ( adapter ), ĊĠĠĠĠĠĠĠ ĠAsync Differ Config . Builder < T >( diff Callback ). build () ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġm List : ĠList < T >? Ġ= Ġnull ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGet Ġthe Ġcurrent ĠList Ġ- Ġany Ġdiff ing Ġto Ġpresent Ġthis Ġlist Ġhas Ġalready Ġbeen Ġcomputed Ġand ĊĠĠĠĠ Ġ* Ġdis patched Ġvia Ġthe ĠList Update Callback . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠIf Ġa Ġ` null ` ĠList , Ġor Ġno ĠList Ġhas Ġbeen Ġsubmitted , Ġan Ġempty Ġlist Ġwill Ġbe Ġreturned . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThe Ġreturned Ġlist Ġmay Ġnot Ġbe Ġmut ated Ġ- Ġmutations Ġto Ġcontent Ġmust Ġbe Ġdone Ġthrough ĊĠĠĠĠ Ġ* Ġ[. submit List ]. ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return Ġcurrent ĠList . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠNon - null , Ġun modifiable Ġversion Ġof Ġm List . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠCollections . emptyList Ġwhen Ġm List Ġis Ġnull , Ġwrapped Ġby ĠCollections . unmodifiable List Ġotherwise ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġvar Ġcurrent List : ĠList < T > Ġ= Ġempty List () ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠ Ġ// ĠMax Ġgeneration Ġof Ġcurrently Ġscheduled Ġrunnable ĊĠĠĠ Ġvar Ġm Max Scheduled Generation Ġ= Ġ 0 ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠPass Ġa Ġnew ĠList Ġto Ġthe ĠAdapter Helper . ĠAdapter Ġupdates Ġwill Ġbe Ġcomputed Ġon Ġa Ġbackground ĊĠĠĠĠ Ġ* Ġthread . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠIf Ġa ĠList Ġis Ġalready Ġpresent , Ġa Ġdiff Ġwill Ġbe Ġcomputed Ġasynchronously Ġon Ġa Ġbackground Ġthread . ĊĠĠĠĠ Ġ* ĠWhen Ġthe Ġdiff Ġis Ġcomputed , Ġit Ġwill Ġbe Ġapplied Ġ( dis patched Ġto Ġthe Ġ[ List Update Callback ]), ĊĠĠĠĠ Ġ* Ġand Ġthe Ġnew ĠList Ġwill Ġbe Ġsw apped Ġin . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThe Ġcommit Ġcallback Ġcan Ġbe Ġused Ġto Ġknow Ġwhen Ġthe ĠList Ġis Ġcommitted , Ġbut Ġnote Ġthat Ġit ĊĠĠĠĠ Ġ* Ġmay Ġnot Ġbe Ġexecuted . ĠIf ĠList ĠB Ġis Ġsubmitted Ġimmediately Ġafter ĠList ĠA , Ġand Ġis ĊĠĠĠĠ Ġ* Ġcommitted Ġdirectly , Ġthe Ġcallback Ġassociated Ġwith ĠList ĠA Ġwill Ġnot Ġbe Ġrun . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġnew List ĠThe Ġnew ĠList . ĊĠĠĠĠ Ġ* Ġ@ param Ġcommit Callback ĠOptional Ġrunnable Ġthat Ġis Ġexecuted Ġwhen Ġthe ĠList Ġis Ġcommitted , Ġif ĊĠĠĠĠ Ġ* Ġit Ġis Ġcommitted . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠPass Ġa Ġnew ĠList Ġto Ġthe ĠAdapter Helper . ĠAdapter Ġupdates Ġwill Ġbe Ġcomputed Ġon Ġa Ġbackground ĊĠĠĠĠ Ġ* Ġthread . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠIf Ġa ĠList Ġis Ġalready Ġpresent , Ġa Ġdiff Ġwill Ġbe Ġcomputed Ġasynchronously Ġon Ġa Ġbackground Ġthread . ĊĠĠĠĠ Ġ* ĠWhen Ġthe Ġdiff Ġis Ġcomputed , Ġit Ġwill Ġbe Ġapplied Ġ( dis patched Ġto Ġthe Ġ[ List Update Callback ]), ĊĠĠĠĠ Ġ* Ġand Ġthe Ġnew ĠList Ġwill Ġbe Ġsw apped Ġin . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġnew List ĠThe Ġnew ĠList . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Jvm Over loads ĊĠĠĠ Ġfun Ġsubmit List ( ĊĠĠĠĠĠĠĠ Ġnew List : ĠList < T > ?, ĊĠĠĠĠĠĠĠ Ġcommit Callback : ĠRunnable ? Ġ= Ġnull ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġincrement ing Ġgeneration Ġmeans Ġany Ġcurrently - running Ġdiffs Ġare Ġdiscarded Ġwhen Ġthey Ġfinish ĊĠĠĠĠĠĠĠ Ġval Ġrun Generation Ġ= Ġ++ m Max Scheduled Generation ĊĠĠĠĠĠĠĠ Ġif Ġ( new List Ġ=== Ġm List ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġnothing Ġto Ġdo Ġ( Note Ġ- Ġstill Ġhad Ġto Ġinc Ġgeneration , Ġsince Ġmay Ġhave Ġongoing Ġwork ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcommit Callback ?. run () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġprevious List Ġ= Ġcurrent List ĊĊĠĠĠĠĠĠĠ Ġ// Ġfast Ġsimple Ġremove Ġall ĊĠĠĠĠĠĠĠ Ġif Ġ( new List Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcount Removed Ġ= Ġm List !!. size ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm List Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent List Ġ= Ġempty List () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġnotify Ġlast , Ġafter Ġlist Ġis Ġupdated ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Update Callback . on Removed ( 0 , Ġcount Removed ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Current List Changed ( previous List , Ġcommit Callback ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġfast Ġsimple Ġfirst Ġinsert ĊĠĠĠĠĠĠĠ Ġif Ġ( m List Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm List Ġ= Ġnew List ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent List Ġ= ĠCollections . unmodifiable List ( new List ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġnotify Ġlast , Ġafter Ġlist Ġis Ġupdated ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Update Callback . on Inserted ( 0 , Ġnew List . size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Current List Changed ( previous List , Ġcommit Callback ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġold List : ĠList < T > Ġ= Ġm List !! ĊĠĠĠĠĠĠĠ Ġm Config . background Thread Executor . execute Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDiff Util . calculate Diff ( object Ġ: ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDiff Util . Callback () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġget Old List Size (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġold List . size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġget New List Size (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnew List . size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġare Items The Same ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġold Item Position : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Item Position : ĠInt ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġold Item : ĠT ? Ġ= Ġold List [ old Item Position ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Item : ĠT ? Ġ= Ġnew List [ new Item Position ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( old Item Ġ!= Ġnull Ġ&& Ġnew Item Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Config . diff Callback . are Items The Same ( old Item , Ġnew Item ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġold Item Ġ== Ġnull Ġ&& Ġnew Item Ġ== Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġboth Ġitems Ġare Ġnull Ġwe Ġconsider Ġthem Ġthe Ġsame . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġare Contents The Same ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġold Item Position : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Item Position : ĠInt ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġold Item : ĠT ? Ġ= Ġold List [ old Item Position ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Item : ĠT ? Ġ= Ġnew List [ new Item Position ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( old Item Ġ!= Ġnull Ġ&& Ġnew Item Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġm Config . diff Callback ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. are Contents The Same ( old Item , Ġnew Item ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( old Item Ġ== Ġnull Ġ&& Ġnew Item Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠAssertionError () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġget Change Payload ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġold Item Position : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Item Position : ĠInt ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġold Item : ĠT ? Ġ= Ġold List [ old Item Position ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Item : ĠT ? Ġ= Ġnew List [ new Item Position ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( old Item Ġ!= Ġnull Ġ&& Ġnew Item Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġm Config . diff Callback . get Change Payload ( old Item , Ġnew Item ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠAssertionError () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm MainThread Executor . execute Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( m Max Scheduled Generation Ġ== Ġrun Generation ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġl atch List ( new List , Ġresult , Ġcommit Callback ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġ Ġ/* Ġsynthetic Ġaccess Ġ*/ latch List ( ĊĠĠĠĠĠĠĠ Ġnew List : ĠList < T >, ĊĠĠĠĠĠĠĠ Ġdiff Result : ĠDiff Result , ĊĠĠĠĠĠĠĠ Ġcommit Callback : ĠRunnable ? ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġprevious List Ġ= Ġcurrent List ĊĠĠĠĠĠĠĠ Ġm List Ġ= Ġnew List ĊĠĠĠĠĠĠĠ Ġ// Ġnotify Ġlast , Ġafter Ġlist Ġis Ġupdated ĊĠĠĠĠĠĠĠ Ġcurrent List Ġ= ĠCollections . unmodifiable List ( new List ) ĊĠĠĠĠĠĠĠ Ġdiff Result . dispatch Updates To ( m Update Callback ) ĊĠĠĠĠĠĠĠ Ġon Current List Changed ( previous List , Ġcommit Callback ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġon Current List Changed ( ĊĠĠĠĠĠĠĠ Ġprevious List : ĠList < T >, ĊĠĠĠĠĠĠĠ Ġcommit Callback : ĠRunnable ? ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġcurrent Ġlist Ġis Ġalways Ġm ReadOnly List ĊĠĠĠĠĠĠĠ Ġfor Ġ( listener Ġin Ġm Listeners ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlistener . on Current List Changed ( previous List , Ġcurrent List ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcommit Callback ?. run () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAdd Ġa ĠList Listener Ġto Ġreceive Ġupdates Ġwhen Ġthe Ġcurrent ĠList Ġchanges . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġlistener ĠListener Ġto Ġreceive Ġupdates . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ see Ġ. getCurrent List ĊĠĠĠĠ Ġ* Ġ@ see Ġ. remove List Listener ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġadd List Listener ( listener : ĠList Listener < T >) Ġ{ ĊĠĠĠĠĠĠĠ Ġm Listeners . add ( listener ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRemove Ġa Ġpreviously Ġregistered ĠList Listener . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġlistener ĠPrevious ly Ġregistered Ġlistener . ĊĠĠĠĠ Ġ* Ġ@ see Ġ. getCurrent List ĊĠĠĠĠ Ġ* Ġ@ see Ġ. add List Listener ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġremove List Listener ( listener : ĠList Listener < T >) Ġ{ ĊĠĠĠĠĠĠĠ Ġm Listeners . remove ( listener ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġs MainThread Executor : ĠExecutor Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMain Thread Executor () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCreate Ġa ĠAsync List Differ Ġwith Ġthe Ġprovided Ġconfig , Ġand ĠList Update Callback Ġto Ġdispatch ĊĠĠĠĠ Ġ* Ġupdates Ġto . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġlist Update Callback ĠCallback Ġto Ġdispatch Ġupdates Ġto . ĊĠĠĠĠ Ġ* Ġ@ param Ġconfig ĠConfig Ġto Ġdefine Ġbackground Ġwork ĠExecutor , Ġand ĠDiff Util . Item Callback Ġfor ĊĠĠĠĠ Ġ* Ġcomputing ĠList Ġdiffs . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ see ĠDiff Util . Diff Result . dispatch Updates To ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġm MainThread Executor Ġ= Ġs MainThread Executor ĊĠĠĠ Ġ} Ċ } Ċ