Skip to content

Use singleton Operators where we can #2905

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

Merged
merged 1 commit into from
Apr 23, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 27 additions & 7 deletions src/main/java/rx/Observable.java
Original file line number Diff line number Diff line change
Expand Up @@ -2295,7 +2295,7 @@ public final Observable<Observable<T>> nest() {
* @see <a href="http://reactivex.io/documentation/operators/empty-never-throw.html">ReactiveX operators documentation: Never</a>
*/
public final static <T> Observable<T> never() {
return new NeverObservable<T>();
return NeverObservable.instance();
}

/**
Expand Down Expand Up @@ -4026,7 +4026,7 @@ public final <T2> Observable<T2> dematerialize() {
* @see <a href="http://reactivex.io/documentation/operators/distinct.html">ReactiveX operators documentation: Distinct</a>
*/
public final Observable<T> distinct() {
return lift(new OperatorDistinct<T, T>(UtilityFunctions.<T>identity()));
return lift(OperatorDistinct.<T> instance());
}

/**
Expand Down Expand Up @@ -4064,7 +4064,7 @@ public final <U> Observable<T> distinct(Func1<? super T, ? extends U> keySelecto
* @see <a href="http://reactivex.io/documentation/operators/distinct.html">ReactiveX operators documentation: Distinct</a>
*/
public final Observable<T> distinctUntilChanged() {
return lift(new OperatorDistinctUntilChanged<T, T>(UtilityFunctions.<T>identity()));
return lift(OperatorDistinctUntilChanged.<T> instance());
}

/**
Expand Down Expand Up @@ -4959,8 +4959,13 @@ public final Observable<T> ignoreElements() {
* @return an Observable that emits a Boolean
* @see <a href="http://reactivex.io/documentation/operators/contains.html">ReactiveX operators documentation: Contains</a>
*/
@SuppressWarnings("unchecked")
public final Observable<Boolean> isEmpty() {
return lift(new OperatorAny<T>(UtilityFunctions.alwaysTrue(), true));
return lift((OperatorAny<T>) HolderAnyForEmpty.INSTANCE);
}

private static class HolderAnyForEmpty {
static final OperatorAny<?> INSTANCE = new OperatorAny<Object>(UtilityFunctions.alwaysTrue(), true);
}

/**
Expand Down Expand Up @@ -5226,7 +5231,7 @@ public final Boolean call(T t) {
* @see <a href="http://reactivex.io/documentation/operators/backpressure.html">ReactiveX operators documentation: backpressure operators</a>
*/
public final Observable<T> onBackpressureBuffer() {
return lift(new OperatorOnBackpressureBuffer<T>());
return lift(OperatorOnBackpressureBuffer.<T> instance());
}

/**
Expand Down Expand Up @@ -6709,7 +6714,7 @@ public final Observable<T> share() {
* @see <a href="http://reactivex.io/documentation/operators/first.html">ReactiveX operators documentation: First</a>
*/
public final Observable<T> single() {
return lift(new OperatorSingle<T>());
return lift(OperatorSingle.<T> instance());
}

/**
Expand Down Expand Up @@ -9276,7 +9281,22 @@ public final <T2, R> Observable<R> zipWith(Observable<? extends T2> other, Func2
* the type of item (not) emitted by the Observable
*/
private static class NeverObservable<T> extends Observable<T> {
public NeverObservable() {

private static class Holder {
static final NeverObservable<?> INSTANCE = new NeverObservable<Object>();
}

/**
* Returns a singleton instance of NeverObservble (cast to the generic type).
*
* @return
*/
@SuppressWarnings("unchecked")
static <T> NeverObservable<T> instance() {
return (NeverObservable<T>) Holder.INSTANCE;
}

NeverObservable() {
super(new OnSubscribe<T>() {

@Override
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/rx/internal/operators/OperatorDistinct.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@

import java.util.HashSet;
import java.util.Set;

import rx.Observable.Operator;
import rx.Subscriber;
import rx.functions.Func1;
import rx.internal.util.UtilityFunctions;

/**
* Returns an Observable that emits all distinct items emitted by the source.
Expand All @@ -29,6 +31,21 @@
*/
public final class OperatorDistinct<T, U> implements Operator<T, T> {
final Func1<? super T, ? extends U> keySelector;

private static class Holder {
static final OperatorDistinct<?,?> INSTANCE = new OperatorDistinct<Object,Object>(UtilityFunctions.<Object>identity());
}

/**
* Returns a singleton instance of OperatorDistinct that was built using
* the identity function for comparison (<code>new OperatorDistinct(UtilityFunctions.identity())</code>).
*
* @return Operator that emits distinct values only (regardless of order) using the identity function for comparison
*/
@SuppressWarnings("unchecked")
Copy link
Member

Choose a reason for hiding this comment

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

I'd add a javadoc comment here so it is more apparent the returned instance uses the identity function for comparison.

public static <T> OperatorDistinct<T,T> instance() {
return (OperatorDistinct<T, T>) Holder.INSTANCE;
}

public OperatorDistinct(Func1<? super T, ? extends U> keySelector) {
this.keySelector = keySelector;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import rx.Observable.Operator;
import rx.Subscriber;
import rx.functions.Func1;
import rx.internal.util.UtilityFunctions;

/**
* Returns an Observable that emits all sequentially distinct items emitted by the source.
Expand All @@ -26,6 +27,22 @@
*/
public final class OperatorDistinctUntilChanged<T, U> implements Operator<T, T> {
final Func1<? super T, ? extends U> keySelector;

private static class Holder {
static final OperatorDistinctUntilChanged<?,?> INSTANCE = new OperatorDistinctUntilChanged<Object,Object>(UtilityFunctions.identity());
}


/**
* Returns a singleton instance of OperatorDistinctUntilChanged that was built using
* the identity function for comparison (<code>new OperatorDistinctUntilChanged(UtilityFunctions.identity())</code>).
*
* @return Operator that emits sequentially distinct values only using the identity function for comparison
*/
@SuppressWarnings("unchecked")
Copy link
Member

Choose a reason for hiding this comment

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

Same javadoc here as above.

public static <T> OperatorDistinctUntilChanged<T,T> instance() {
return (OperatorDistinctUntilChanged<T, T>) Holder.INSTANCE;
}

public OperatorDistinctUntilChanged(Func1<? super T, ? extends U> keySelector) {
this.keySelector = keySelector;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,16 @@ public class OperatorOnBackpressureBuffer<T> implements Operator<T, T> {
private final Long capacity;
private final Action0 onOverflow;

public OperatorOnBackpressureBuffer() {
private static class Holder {
static final OperatorOnBackpressureBuffer<?> INSTANCE = new OperatorOnBackpressureBuffer<Object>();
}

@SuppressWarnings("unchecked")
public static <T> OperatorOnBackpressureBuffer<T> instance() {
return (OperatorOnBackpressureBuffer<T>) Holder.INSTANCE;
}

private OperatorOnBackpressureBuffer() {
this.capacity = null;
this.onOverflow = null;
}
Expand Down
17 changes: 16 additions & 1 deletion src/main/java/rx/internal/operators/OperatorSingle.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,22 @@ public final class OperatorSingle<T> implements Operator<T, T> {
private final boolean hasDefaultValue;
private final T defaultValue;

public OperatorSingle() {
private static class Holder {
final static OperatorSingle<?> INSTANCE = new OperatorSingle<Object>();
}

/**
* Returns a singleton instance of OperatorSingle (if the stream is empty or has
* more than one element an error will be emitted) that is cast to the generic type.
*
* @return a singleton instance of an Operator that will emit a single value only unless the stream has zero or more than one element in which case it will emit an error.
*/
@SuppressWarnings("unchecked")
public static <T> OperatorSingle<T> instance() {
return (OperatorSingle<T>) Holder.INSTANCE;
}

private OperatorSingle() {
this(false, null);
}

Expand Down