### Question:
LiveDataUtils { public static <In, Out> LiveData<Out> dedupedMappedLiveDataFor( @NonNull LiveData<In> inputLiveData, @NonNull final Function<In, Out> mappingMethod) { final MediatorLiveData<Out> outputLiveData = new MediatorLiveData<>(); outputLiveData.addSource(inputLiveData, new Observer<In>() { @Override public void onChanged(@Nullable final In input) { WorkManagerTaskExecutor.getInstance().executeOnBackgroundThread(new Runnable() { @Override public void run() { synchronized (outputLiveData) { Out newOutput = mappingMethod.apply(input); Out previousOutput = outputLiveData.getValue(); if (previousOutput == null && newOutput != null) { outputLiveData.postValue(newOutput); } else if ( previousOutput != null && !previousOutput.equals(newOutput)) { outputLiveData.postValue(newOutput); } } } }); } }); return outputLiveData; } private  LiveDataUtils(); static LiveData<Out> dedupedMappedLiveDataFor(
            @NonNull LiveData<In> inputLiveData,
            @NonNull final Function<In, Out> mappingMethod);  }### Answer:
@Test public void testDedupedMappedLiveData_dedupesValues() { Function<String, String> identityMapping = new Function<String, String>() { @Override public String apply(String input) { return input; } }; MutableLiveData<String> originalLiveData = new MutableLiveData<>(); LiveData<String> dedupedLiveData = LiveDataUtils.dedupedMappedLiveDataFor(originalLiveData, identityMapping); assertThat(dedupedLiveData.getValue(), is(nullValue())); TestLifecycleOwner testLifecycleOwner = new TestLifecycleOwner(); CountingObserver<String> observer = new CountingObserver<>(); dedupedLiveData.observe(testLifecycleOwner, observer); assertThat(observer.mTimesUpdated, is(0)); String value = "new value"; originalLiveData.setValue(value); assertThat(dedupedLiveData.getValue(), is(value)); assertThat(observer.mTimesUpdated, is(1)); originalLiveData.setValue(value); assertThat(dedupedLiveData.getValue(), is(value)); assertThat(observer.mTimesUpdated, is(1)); String newerValue = "newer value"; originalLiveData.setValue(newerValue); assertThat(dedupedLiveData.getValue(), is(newerValue)); assertThat(observer.mTimesUpdated, is(2)); dedupedLiveData.removeObservers(testLifecycleOwner); }
@Test public void testDedupedMappedLiveData_mapsValues() { Function<Integer, String> intToStringMapping = new Function<Integer, String>() { @Override public String apply(Integer input) { return (input == null) ? "" : input.toString(); } }; MutableLiveData<Integer> originalLiveData = new MutableLiveData<>(); LiveData<String> mappedLiveData = LiveDataUtils.dedupedMappedLiveDataFor( originalLiveData, intToStringMapping); assertThat(mappedLiveData.getValue(), is(nullValue())); TestLifecycleOwner testLifecycleOwner = new TestLifecycleOwner(); CountingObserver<String> observer = new CountingObserver<>(); mappedLiveData.observe(testLifecycleOwner, observer); assertThat(observer.mTimesUpdated, is(0)); Integer value = null; originalLiveData.setValue(value); assertThat(mappedLiveData.getValue(), is("")); value = 1337; originalLiveData.setValue(value); assertThat(mappedLiveData.getValue(), is(value.toString())); value = -0; originalLiveData.setValue(value); assertThat(mappedLiveData.getValue(), is(value.toString())); mappedLiveData.removeObservers(testLifecycleOwner); }