title: Changes in MutableLiveData is reflected in observers before explicitly setting value
body: <p>In the ViewModel, I have a MutableLiveData whose generic type is a list of custom objects. The object has a <code>selected</code> field which can be changed from the UI. Now, I am using a RecyclerView to populate the UI and DiffUtil.Callback to dispatch the right changes.</p>
  
  <p>When the checkbox in the ViewHolder is checked, a callback in the Fragment (containing the RecyclerView) get notified. And then a method in the ViewHolder is called to change the <code>selected</code> value of the item and then subsequently calls <code>setValue</code>.</p>
  
  <p><strong>Fragment</strong></p>
  
  <pre><code>private fun observeViewModel() {
      viewModel.data.observe(viewLifecycleOwner, Observer {
          adapter.updateItems(items)
          this.items = items
      })
  }
  
  override fun onSelectionChange(position: Int) {
      viewModel.reverseSelection(position)
  }
  </code></pre>
  
  <p><strong>ViewModel</strong></p>
  
  <pre><code>fun reverseSelection(index: Int) {
      data.value?.let {
          if (it.size &gt; index) {
              it[index].selected = !it[index].selected
              data.value = it
          }
      }
  
  }
  </code></pre>
  
  <p><strong>RecyclerView Adapter</strong></p>
  
  <pre><code>fun updateItems(items: List&lt;T&gt;) {
      val diffCallback = BaseDiffCallback(this.items, items)
      val diffResult = DiffUtil.calculateDiff(diffCallback, false)
      this.items = items
      diffResult.dispatchUpdatesTo(this)
  }
  </code></pre>
  
  <p>The issue is that DiffUtil is not detecting any changes because it appears the <code>items</code> field in the Fragment and the data value in the ViewHolder are pointing to the same object in memory. With log statements, I noticed that the items in the fragment already reflects the changes before explicitly calling <code>setValue</code> on the data in the ViewHolder and before triggering the observer.</p>
  
  <p>Please, how can I change the <code>selection</code> state without the items in the Fragment reflecting the state until I call <code>setValue</code> in the ViewHolder?</p>
  
  <hr>
  
  <h2>EDIT</h2>
  
  <p>I really appreciate the kind users who took their time to provide solutions to my question. However because I didn't explain my question well enough, the proposed solutions didn't work for me.</p>
  
  <p>One of the critical details I missed out is that I am using databinding and the checked state of the model determines the state of the other views in the <code>ViewHolder</code>. Additionally, I made a typo earlier, <code>reverseSelection</code> is not in the <code>ViewHolder</code> but <code>ViewModel</code>. Finally, I am using both the <code>Adapter</code> and the <code>ViewHolder</code> for other data models.</p>
  
  <p>So, it's very important that the <code>selected</code> variable reside in the data class otherwise, there'll be a performance overhead when looking through the elements in the HashMap or Set; checking if the item at <code>position</code> is selected or not. The data set can be quite large. Additionally, because I am using the <code>RecyclerView.Adapter</code> and <code>ViewHolder</code> for other data models, I feel using a HashMap or a Set is not the best solution.</p>
  
  <p>For now, I am no longer depending on the ViewHolder to handle propagation of the changed data model. The new updates are thus:</p>
  
  <p><strong>ViewModel</strong></p>
  
  <pre><code>fun reverseSelection(index: Int): Boolean {
      return data.value?.let {
          if (it.size &gt; index) {
              it[index].selected = !it[index].selected
              true
          } else false
      } ?: false
  
  }
  </code></pre>
  
  <p><strong>Fragment</strong></p>
  
  <pre><code>override fun onSelectionChange(position: Int) {
          if (viewModel.reverseSelection(position)) {
              adapter.notifyItemChanged(position, 0)
          }
      }
  </code></pre>
  
  <p>I don't know if this is the best solution but I will make do with it for now.</p>