Почему в DiffUtil два Callback’а, а не один

«Почему в DiffUtil два Callback’а, а не один» — вопрос из категории UI и Views, который задают на 23% собеседований Android Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

DiffUtil использует два Callback'а (DiffUtil.Callback и DiffUtil.ItemCallback) для разделения логики сравнения элементов и их идентификации.

DiffUtil.Callback (для RecyclerView.Adapter):

  • Сравнивает старый и новый списки целиком
  • Используется в ListAdapter/AsyncListDiffer
  • Требует реализации getOldListSize(), getNewListSize(), areItemsTheSame(), areContentsTheSame()

ItemCallback (для AsyncListDiffer):

  • Оптимизирован для пошагового сравнения
  • Упрощает работу с Paging и асинхронными обновлениями

Пример ItemCallback:

val diffCallback = object : DiffUtil.ItemCallback<User>() {
    override fun areItemsTheSame(old: User, new: User) = old.id == new.id
    override fun areContentsTheSame(old: User, new: User) = old == new
}