Skip to content

Commit 363f038

Browse files
authored
2.x: Detail distinct() & distinctUntilChanged() in JavaDoc (ReactiveX#5837)
* 2.x: Detail distinct() & distinctUntilChanged() in JavaDoc * Address feedback
1 parent 68f94f0 commit 363f038

File tree

2 files changed

+135
-10
lines changed

2 files changed

+135
-10
lines changed

src/main/java/io/reactivex/Flowable.java

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7669,9 +7669,24 @@ public final <T2> Flowable<T2> dematerialize() {
76697669
}
76707670

76717671
/**
7672-
* Returns a Flowable that emits all items emitted by the source Publisher that are distinct.
7672+
* Returns a Flowable that emits all items emitted by the source Publisher that are distinct
7673+
* based on {@link Object#equals(Object)} comparison.
76737674
* <p>
76747675
* <img width="640" height="310" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/distinct.png" alt="">
7676+
* <p>
7677+
* It is recommended the elements' class {@code T} in the flow overrides the default {@code Object.equals()} and {@link Object#hashCode()} to provide
7678+
* meaningful comparison between items as the default Java implementation only considers reference equivalence.
7679+
* <p>
7680+
* By default, {@code distinct()} uses an internal {@link java.util.HashSet} per Subscriber to remember
7681+
* previously seen items and uses {@link java.util.Set#add(Object)} returning {@code false} as the
7682+
* indicator for duplicates.
7683+
* <p>
7684+
* Note that this internal {@code HashSet} may grow unbounded as items won't be removed from it by
7685+
* the operator. Therefore, using very long or infinite upstream (with very distinct elements) may lead
7686+
* to {@code OutOfMemoryError}.
7687+
* <p>
7688+
* Customizing the retention policy can happen only by providing a custom {@link java.util.Collection} implementation
7689+
* to the {@link #distinct(Function, Callable)} overload.
76757690
* <dl>
76767691
* <dt><b>Backpressure:</b></dt>
76777692
* <dd>The operator doesn't interfere with backpressure which is determined by the source {@code Publisher}'s
@@ -7683,6 +7698,8 @@ public final <T2> Flowable<T2> dematerialize() {
76837698
* @return a Flowable that emits only those items emitted by the source Publisher that are distinct from
76847699
* each other
76857700
* @see <a href="http://reactivex.io/documentation/operators/distinct.html">ReactiveX operators documentation: Distinct</a>
7701+
* @see #distinct(Function)
7702+
* @see #distinct(Function, Callable)
76867703
*/
76877704
@SuppressWarnings({ "rawtypes", "unchecked" })
76887705
@CheckReturnValue
@@ -7694,9 +7711,24 @@ public final Flowable<T> distinct() {
76947711

76957712
/**
76967713
* Returns a Flowable that emits all items emitted by the source Publisher that are distinct according
7697-
* to a key selector function.
7714+
* to a key selector function and based on {@link Object#equals(Object)} comparison of the objects
7715+
* returned by the key selector function.
76987716
* <p>
76997717
* <img width="640" height="310" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/distinct.key.png" alt="">
7718+
* <p>
7719+
* It is recommended the keys' class {@code K} overrides the default {@code Object.equals()} and {@link Object#hashCode()} to provide
7720+
* meaningful comparison between the key objects as the default Java implementation only considers reference equivalence.
7721+
* <p>
7722+
* By default, {@code distinct()} uses an internal {@link java.util.HashSet} per Subscriber to remember
7723+
* previously seen keys and uses {@link java.util.Set#add(Object)} returning {@code false} as the
7724+
* indicator for duplicates.
7725+
* <p>
7726+
* Note that this internal {@code HashSet} may grow unbounded as keys won't be removed from it by
7727+
* the operator. Therefore, using very long or infinite upstream (with very distinct keys) may lead
7728+
* to {@code OutOfMemoryError}.
7729+
* <p>
7730+
* Customizing the retention policy can happen only by providing a custom {@link java.util.Collection} implementation
7731+
* to the {@link #distinct(Function, Callable)} overload.
77007732
* <dl>
77017733
* <dt><b>Backpressure:</b></dt>
77027734
* <dd>The operator doesn't interfere with backpressure which is determined by the source {@code Publisher}'s
@@ -7711,6 +7743,7 @@ public final Flowable<T> distinct() {
77117743
* is distinct from another one or not
77127744
* @return a Flowable that emits those items emitted by the source Publisher that have distinct keys
77137745
* @see <a href="http://reactivex.io/documentation/operators/distinct.html">ReactiveX operators documentation: Distinct</a>
7746+
* @see #distinct(Function, Callable)
77147747
*/
77157748
@CheckReturnValue
77167749
@BackpressureSupport(BackpressureKind.FULL)
@@ -7721,9 +7754,13 @@ public final <K> Flowable<T> distinct(Function<? super T, K> keySelector) {
77217754

77227755
/**
77237756
* Returns a Flowable that emits all items emitted by the source Publisher that are distinct according
7724-
* to a key selector function.
7757+
* to a key selector function and based on {@link Object#equals(Object)} comparison of the objects
7758+
* returned by the key selector function.
77257759
* <p>
77267760
* <img width="640" height="310" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/distinct.key.png" alt="">
7761+
* <p>
7762+
* It is recommended the keys' class {@code K} overrides the default {@code Object.equals()} and {@link Object#hashCode()} to provide
7763+
* meaningful comparison between the key objects as the default Java implementation only considers reference equivalence.
77277764
* <dl>
77287765
* <dt><b>Backpressure:</b></dt>
77297766
* <dd>The operator doesn't interfere with backpressure which is determined by the source {@code Publisher}'s
@@ -7754,9 +7791,18 @@ public final <K> Flowable<T> distinct(Function<? super T, K> keySelector,
77547791

77557792
/**
77567793
* Returns a Flowable that emits all items emitted by the source Publisher that are distinct from their
7757-
* immediate predecessors.
7794+
* immediate predecessors based on {@link Object#equals(Object)} comparison.
77587795
* <p>
77597796
* <img width="640" height="310" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/distinctUntilChanged.png" alt="">
7797+
* <p>
7798+
* It is recommended the elements' class {@code T} in the flow overrides the default {@code Object.equals()} to provide
7799+
* meaningful comparison between items as the default Java implementation only considers reference equivalence.
7800+
* Alternatively, use the {@link #distinctUntilChanged(BiPredicate)} overload and provide a comparison function
7801+
* in case the class {@code T} can't be overridden with custom {@code equals()} or the comparison itself
7802+
* should happen on different terms or properties of the class {@code T}.
7803+
* <p>
7804+
* Note that the operator always retains the latest item from upstream regardless of the comparison result
7805+
* and uses it in the next comparison with the next upstream item.
77607806
* <dl>
77617807
* <dt><b>Backpressure:</b></dt>
77627808
* <dd>The operator doesn't interfere with backpressure which is determined by the source {@code Publisher}'s
@@ -7768,6 +7814,7 @@ public final <K> Flowable<T> distinct(Function<? super T, K> keySelector,
77687814
* @return a Flowable that emits those items from the source Publisher that are distinct from their
77697815
* immediate predecessors
77707816
* @see <a href="http://reactivex.io/documentation/operators/distinct.html">ReactiveX operators documentation: Distinct</a>
7817+
* @see #distinctUntilChanged(BiPredicate)
77717818
*/
77727819
@CheckReturnValue
77737820
@BackpressureSupport(BackpressureKind.FULL)
@@ -7778,9 +7825,20 @@ public final Flowable<T> distinctUntilChanged() {
77787825

77797826
/**
77807827
* Returns a Flowable that emits all items emitted by the source Publisher that are distinct from their
7781-
* immediate predecessors, according to a key selector function.
7828+
* immediate predecessors, according to a key selector function and based on {@link Object#equals(Object)} comparison
7829+
* of those objects returned by the key selector function.
77827830
* <p>
77837831
* <img width="640" height="310" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/distinctUntilChanged.key.png" alt="">
7832+
* <p>
7833+
* It is recommended the keys' class {@code K} overrides the default {@code Object.equals()} to provide
7834+
* meaningful comparison between the key objects as the default Java implementation only considers reference equivalence.
7835+
* Alternatively, use the {@link #distinctUntilChanged(BiPredicate)} overload and provide a comparison function
7836+
* in case the class {@code K} can't be overridden with custom {@code equals()} or the comparison itself
7837+
* should happen on different terms or properties of the item class {@code T} (for which the keys can be
7838+
* derived via a similar selector).
7839+
* <p>
7840+
* Note that the operator always retains the latest key from upstream regardless of the comparison result
7841+
* and uses it in the next comparison with the next key derived from the next upstream item.
77847842
* <dl>
77857843
* <dt><b>Backpressure:</b></dt>
77867844
* <dd>The operator doesn't interfere with backpressure which is determined by the source {@code Publisher}'s
@@ -7810,6 +7868,9 @@ public final <K> Flowable<T> distinctUntilChanged(Function<? super T, K> keySele
78107868
* immediate predecessors when compared with each other via the provided comparator function.
78117869
* <p>
78127870
* <img width="640" height="310" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/distinctUntilChanged.png" alt="">
7871+
* <p>
7872+
* Note that the operator always retains the latest item from upstream regardless of the comparison result
7873+
* and uses it in the next comparison with the next upstream item.
78137874
* <dl>
78147875
* <dt><b>Backpressure:</b></dt>
78157876
* <dd>The operator doesn't interfere with backpressure which is determined by the source {@code Publisher}'s

src/main/java/io/reactivex/Observable.java

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7011,9 +7011,25 @@ public final <T2> Observable<T2> dematerialize() {
70117011
}
70127012

70137013
/**
7014-
* Returns an Observable that emits all items emitted by the source ObservableSource that are distinct.
7014+
* Returns an Observable that emits all items emitted by the source ObservableSource that are distinct
7015+
* based on {@link Object#equals(Object)} comparison.
70157016
* <p>
70167017
* <img width="640" height="310" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/distinct.png" alt="">
7018+
* <p>
7019+
* It is recommended the elements' class {@code T} in the flow overrides the default {@code Object.equals()}
7020+
* and {@link Object#hashCode()} to provide meaningful comparison between items as the default Java
7021+
* implementation only considers reference equivalence.
7022+
* <p>
7023+
* By default, {@code distinct()} uses an internal {@link java.util.HashSet} per Observer to remember
7024+
* previously seen items and uses {@link java.util.Set#add(Object)} returning {@code false} as the
7025+
* indicator for duplicates.
7026+
* <p>
7027+
* Note that this internal {@code HashSet} may grow unbounded as items won't be removed from it by
7028+
* the operator. Therefore, using very long or infinite upstream (with very distinct elements) may lead
7029+
* to {@code OutOfMemoryError}.
7030+
* <p>
7031+
* Customizing the retention policy can happen only by providing a custom {@link java.util.Collection} implementation
7032+
* to the {@link #distinct(Function, Callable)} overload.
70177033
* <dl>
70187034
* <dt><b>Scheduler:</b></dt>
70197035
* <dd>{@code distinct} does not operate by default on a particular {@link Scheduler}.</dd>
@@ -7022,6 +7038,8 @@ public final <T2> Observable<T2> dematerialize() {
70227038
* @return an Observable that emits only those items emitted by the source ObservableSource that are distinct from
70237039
* each other
70247040
* @see <a href="http://reactivex.io/documentation/operators/distinct.html">ReactiveX operators documentation: Distinct</a>
7041+
* @see #distinct(Function)
7042+
* @see #distinct(Function, Callable)
70257043
*/
70267044
@CheckReturnValue
70277045
@SchedulerSupport(SchedulerSupport.NONE)
@@ -7031,9 +7049,25 @@ public final Observable<T> distinct() {
70317049

70327050
/**
70337051
* Returns an Observable that emits all items emitted by the source ObservableSource that are distinct according
7034-
* to a key selector function.
7052+
* to a key selector function and based on {@link Object#equals(Object)} comparison of the objects
7053+
* returned by the key selector function.
70357054
* <p>
70367055
* <img width="640" height="310" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/distinct.key.png" alt="">
7056+
* <p>
7057+
* It is recommended the keys' class {@code K} overrides the default {@code Object.equals()}
7058+
* and {@link Object#hashCode()} to provide meaningful comparison between the key objects as the default
7059+
* Java implementation only considers reference equivalence.
7060+
* <p>
7061+
* By default, {@code distinct()} uses an internal {@link java.util.HashSet} per Observer to remember
7062+
* previously seen keys and uses {@link java.util.Set#add(Object)} returning {@code false} as the
7063+
* indicator for duplicates.
7064+
* <p>
7065+
* Note that this internal {@code HashSet} may grow unbounded as keys won't be removed from it by
7066+
* the operator. Therefore, using very long or infinite upstream (with very distinct keys) may lead
7067+
* to {@code OutOfMemoryError}.
7068+
* <p>
7069+
* Customizing the retention policy can happen only by providing a custom {@link java.util.Collection} implementation
7070+
* to the {@link #distinct(Function, Callable)} overload.
70377071
* <dl>
70387072
* <dt><b>Scheduler:</b></dt>
70397073
* <dd>{@code distinct} does not operate by default on a particular {@link Scheduler}.</dd>
@@ -7045,6 +7079,7 @@ public final Observable<T> distinct() {
70457079
* is distinct from another one or not
70467080
* @return an Observable that emits those items emitted by the source ObservableSource that have distinct keys
70477081
* @see <a href="http://reactivex.io/documentation/operators/distinct.html">ReactiveX operators documentation: Distinct</a>
7082+
* @see #distinct(Function, Callable)
70487083
*/
70497084
@CheckReturnValue
70507085
@SchedulerSupport(SchedulerSupport.NONE)
@@ -7054,9 +7089,14 @@ public final <K> Observable<T> distinct(Function<? super T, K> keySelector) {
70547089

70557090
/**
70567091
* Returns an Observable that emits all items emitted by the source ObservableSource that are distinct according
7057-
* to a key selector function.
7092+
* to a key selector function and based on {@link Object#equals(Object)} comparison of the objects
7093+
* returned by the key selector function.
70587094
* <p>
70597095
* <img width="640" height="310" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/distinct.key.png" alt="">
7096+
* <p>
7097+
* It is recommended the keys' class {@code K} overrides the default {@code Object.equals()}
7098+
* and {@link Object#hashCode()} to provide meaningful comparison between the key objects as
7099+
* the default Java implementation only considers reference equivalence.
70607100
* <dl>
70617101
* <dt><b>Scheduler:</b></dt>
70627102
* <dd>{@code distinct} does not operate by default on a particular {@link Scheduler}.</dd>
@@ -7082,9 +7122,18 @@ public final <K> Observable<T> distinct(Function<? super T, K> keySelector, Call
70827122

70837123
/**
70847124
* Returns an Observable that emits all items emitted by the source ObservableSource that are distinct from their
7085-
* immediate predecessors.
7125+
* immediate predecessors based on {@link Object#equals(Object)} comparison.
70867126
* <p>
70877127
* <img width="640" height="310" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/distinctUntilChanged.png" alt="">
7128+
* <p>
7129+
* It is recommended the elements' class {@code T} in the flow overrides the default {@code Object.equals()} to provide
7130+
* meaningful comparison between items as the default Java implementation only considers reference equivalence.
7131+
* Alternatively, use the {@link #distinctUntilChanged(BiPredicate)} overload and provide a comparison function
7132+
* in case the class {@code T} can't be overridden with custom {@code equals()} or the comparison itself
7133+
* should happen on different terms or properties of the class {@code T}.
7134+
* <p>
7135+
* Note that the operator always retains the latest item from upstream regardless of the comparison result
7136+
* and uses it in the next comparison with the next upstream item.
70887137
* <dl>
70897138
* <dt><b>Scheduler:</b></dt>
70907139
* <dd>{@code distinctUntilChanged} does not operate by default on a particular {@link Scheduler}.</dd>
@@ -7093,6 +7142,7 @@ public final <K> Observable<T> distinct(Function<? super T, K> keySelector, Call
70937142
* @return an Observable that emits those items from the source ObservableSource that are distinct from their
70947143
* immediate predecessors
70957144
* @see <a href="http://reactivex.io/documentation/operators/distinct.html">ReactiveX operators documentation: Distinct</a>
7145+
* @see #distinctUntilChanged(BiPredicate)
70967146
*/
70977147
@CheckReturnValue
70987148
@SchedulerSupport(SchedulerSupport.NONE)
@@ -7102,9 +7152,20 @@ public final Observable<T> distinctUntilChanged() {
71027152

71037153
/**
71047154
* Returns an Observable that emits all items emitted by the source ObservableSource that are distinct from their
7105-
* immediate predecessors, according to a key selector function.
7155+
* immediate predecessors, according to a key selector function and based on {@link Object#equals(Object)} comparison
7156+
* of those objects returned by the key selector function.
71067157
* <p>
71077158
* <img width="640" height="310" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/distinctUntilChanged.key.png" alt="">
7159+
* <p>
7160+
* It is recommended the keys' class {@code K} overrides the default {@code Object.equals()} to provide
7161+
* meaningful comparison between the key objects as the default Java implementation only considers reference equivalence.
7162+
* Alternatively, use the {@link #distinctUntilChanged(BiPredicate)} overload and provide a comparison function
7163+
* in case the class {@code K} can't be overridden with custom {@code equals()} or the comparison itself
7164+
* should happen on different terms or properties of the item class {@code T} (for which the keys can be
7165+
* derived via a similar selector).
7166+
* <p>
7167+
* Note that the operator always retains the latest key from upstream regardless of the comparison result
7168+
* and uses it in the next comparison with the next key derived from the next upstream item.
71087169
* <dl>
71097170
* <dt><b>Scheduler:</b></dt>
71107171
* <dd>{@code distinctUntilChanged} does not operate by default on a particular {@link Scheduler}.</dd>
@@ -7130,6 +7191,9 @@ public final <K> Observable<T> distinctUntilChanged(Function<? super T, K> keySe
71307191
* immediate predecessors when compared with each other via the provided comparator function.
71317192
* <p>
71327193
* <img width="640" height="310" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/distinctUntilChanged.png" alt="">
7194+
* <p>
7195+
* Note that the operator always retains the latest item from upstream regardless of the comparison result
7196+
* and uses it in the next comparison with the next upstream item.
71337197
* <dl>
71347198
* <dt><b>Scheduler:</b></dt>
71357199
* <dd>{@code distinctUntilChanged} does not operate by default on a particular {@link Scheduler}.</dd>

0 commit comments

Comments
 (0)