Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Javadoc: explain that distinctUntilChanged requires non-mutating data to work as expected #6311

Merged

Conversation

punitda
Copy link
Contributor

@punitda punitda commented Nov 16, 2018

  • Add note in javadoc for all distinctUntilChanged() methods in Flowable and Observable class explaining about unexpected results to expect when using mutable data sources like Mutable CharSequence or Lists.

Resolves: #6290

…e in flow(Observable)

Add few tests for scenarios related to mutable data type flow in distinctUntilChanged() methods for Observable
…e in flow(Flowable)

Add few tests for scenarios related to mutable data type flow in distinctUntilChanged() methods for Flowable
@codecov
Copy link

codecov bot commented Nov 16, 2018

Codecov Report

Merging #6311 into 2.x will decrease coverage by 0.02%.
The diff coverage is n/a.

Impacted file tree graph

@@             Coverage Diff             @@
##                2.x   #6311      +/-   ##
===========================================
- Coverage     98.23%   98.2%   -0.03%     
+ Complexity     6284    6283       -1     
===========================================
  Files           672     672              
  Lines         44992   44992              
  Branches       6223    6223              
===========================================
- Hits          44196   44183      -13     
- Misses          252     267      +15     
+ Partials        544     542       -2
Impacted Files Coverage Δ Complexity Δ
src/main/java/io/reactivex/Flowable.java 100% <ø> (ø) 567 <0> (ø) ⬇️
src/main/java/io/reactivex/Observable.java 100% <ø> (ø) 542 <0> (ø) ⬇️
...ex/internal/operators/flowable/FlowableCreate.java 90% <0%> (-6.78%) 6% <0%> (ø)
.../operators/flowable/FlowableBlockingSubscribe.java 93.02% <0%> (-4.66%) 10% <0%> (-1%)
...ternal/operators/observable/ObservablePublish.java 93.8% <0%> (-4.43%) 10% <0%> (-1%)
...ernal/operators/flowable/FlowableFlatMapMaybe.java 89.37% <0%> (-4.35%) 2% <0%> (ø)
...tivex/internal/observers/FutureSingleObserver.java 94.33% <0%> (-3.78%) 24% <0%> (-1%)
.../internal/disposables/ListCompositeDisposable.java 98% <0%> (-2%) 34% <0%> (-1%)
...rnal/operators/flowable/FlowableFlatMapSingle.java 92.93% <0%> (-1.64%) 2% <0%> (ø)
...io/reactivex/subscribers/SerializedSubscriber.java 98.86% <0%> (-1.14%) 26% <0%> (-1%)
... and 20 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e82b82e...42b56e4. Read the comment docs.

@@ -8740,6 +8740,13 @@ public final Completable concatMapCompletableDelayError(Function<? super T, ? ex
* <p>
* Note that the operator always retains the latest item from upstream regardless of the comparison result
* and uses it in the next comparison with the next upstream item.
* <p>
* Note that if element {@code T} type in the flow is mutable, the comparison of the previous and current
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"element type {@code T}"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. Will fix it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -141,6 +141,84 @@ public void testDistinctUntilChangedOfSourceWithExceptionsFromKeySelector() {
inOrder.verify(w, never()).onComplete();
}

@Test
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no reason to test this unwanted behavior.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I thought initially. Will remove all tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@akarnokd akarnokd merged commit 7058126 into ReactiveX:2.x Nov 16, 2018
* {@code CharSequence}s or {@code List}s where the objects will actually have the same
* references when they are modified and {@code distinctUntilChanged} will evaluate subsequent items as same.
* To avoid such situation, it is recommended that mutable data is converted to an immutable one,
* for example using `map(CharSequence::toString)` or `map(Collections::unmodifiableList)`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Collections::unmodifiableList isn't the right example to use since its a view to the list it is referencing, so if a mutable list is passed then any changes would still reflect the List it returns. Should probably be replaced with ArrayList::new

This documentation is linked to by Collections::unmodifiableList:

Note that changes to the backing collection might still be possible, and if they occur, they are visible through the unmodifiable view. Thus, an unmodifiable view collection is not necessarily immutable. However, if the backing collection of an unmodifiable view is effectively immutable, or if the only reference to the backing collection is through an unmodifiable view, the view can be considered effectively immutable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The best would be ImmutableList::of but we can't depend on external collections libraries.

Perhaps we can have both by list -> Collections.unmodifiableList(new ArrayList<>(list)). This will make a copy of the list but also prevent it from being modified later in the pipeline. Unfortunately, we can't do much about the element mutability, which also affects equals.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, I think we should change map(Collections::unmodifiableList) to map(list -> Collections.unmodifiableList(new ArrayList<>(list)). @akarnokd Let me know if we should go forward with that and I'll create a PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please modify the text as my suggestion.

@punitda punitda deleted the javadocs-distinct-until-changed-method branch November 19, 2018 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants