Skip to content

Commit 357effa

Browse files
committed
Compose generics
1 parent d4ffe95 commit 357effa

File tree

3 files changed

+58
-8
lines changed

3 files changed

+58
-8
lines changed

src/main/java/rx/Observable.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,14 +177,14 @@ public void call(Subscriber<? super R> o) {
177177
@SuppressWarnings("unchecked")
178178
public <R> Observable<R> compose(Transformer<? super T, ? extends R> transformer) {
179179
// Casting to Observable<R> is type-safe because we know Observable is covariant.
180-
return (Observable<R>) transformer.call(this);
180+
return (Observable<R>) ((Transformer<T, ? extends R>) transformer).call(this);
181181
}
182-
182+
183183
/**
184184
* Transformer function used by {@link #compose}.
185185
* @warn more complete description needed
186186
*/
187-
public static interface Transformer<T, R> extends Func1<Observable<? extends T>, Observable<? extends R>> {
187+
public static interface Transformer<T, R> extends Func1<Observable<T>, Observable<? extends R>> {
188188
// cover for generics insanity
189189
}
190190

src/test/java/rx/CovarianceTest.java

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
package rx;
1717

1818
import java.util.ArrayList;
19+
import java.util.Arrays;
20+
import java.util.LinkedHashSet;
21+
import java.util.List;
22+
import java.util.Set;
1923

2024
import org.junit.Test;
2125

@@ -66,7 +70,7 @@ public void testCovarianceOfCompose() {
6670
Observable<Movie> movie2 = movie.compose(new Transformer<Movie, Movie>() {
6771

6872
@Override
69-
public Observable<? extends Movie> call(Observable<? extends Movie> t1) {
73+
public Observable<? extends Movie> call(Observable<Movie> t1) {
7074
return Observable.just(new Movie());
7175
}
7276

@@ -78,7 +82,7 @@ public void testCovarianceOfCompose2() {
7882
Observable<Movie> movie = Observable.<Movie> just(new HorrorMovie());
7983
Observable<HorrorMovie> movie2 = movie.compose(new Transformer<Movie, HorrorMovie>() {
8084
@Override
81-
public Observable<? extends HorrorMovie> call(Observable<? extends Movie> t1) {
85+
public Observable<? extends HorrorMovie> call(Observable<Movie> t1) {
8286
return Observable.just(new HorrorMovie());
8387
}
8488
});
@@ -89,7 +93,7 @@ public void testCovarianceOfCompose3() {
8993
Observable<Movie> movie = Observable.<Movie>just(new HorrorMovie());
9094
Observable<HorrorMovie> movie2 = movie.compose(new Transformer<Movie, HorrorMovie>() {
9195
@Override
92-
public Observable<? extends HorrorMovie> call(Observable<? extends Movie> t1) {
96+
public Observable<? extends HorrorMovie> call(Observable<Movie> t1) {
9397
return Observable.just(new HorrorMovie()).map(new Func1<HorrorMovie, HorrorMovie>() {
9498

9599
@Override
@@ -106,7 +110,7 @@ public void testCovarianceOfCompose4() {
106110
Observable<HorrorMovie> movie = Observable.just(new HorrorMovie());
107111
Observable<HorrorMovie> movie2 = movie.compose(new Transformer<HorrorMovie, HorrorMovie>() {
108112
@Override
109-
public Observable<? extends HorrorMovie> call(Observable<? extends HorrorMovie> t1) {
113+
public Observable<? extends HorrorMovie> call(Observable<HorrorMovie> t1) {
110114
return t1.map(new Func1<HorrorMovie, HorrorMovie>() {
111115

112116
@Override
@@ -118,6 +122,52 @@ public HorrorMovie call(HorrorMovie horrorMovie) {
118122
});
119123
}
120124

125+
@Test
126+
public void testComposeWithDeltaLogic() {
127+
List<Movie> list1 = Arrays.asList(new Movie(), new HorrorMovie(), new ActionMovie());
128+
List<Movie> list2 = Arrays.asList(new ActionMovie(), new Movie(), new HorrorMovie(), new ActionMovie());
129+
Observable<List<Movie>> movies = Observable.just(list1, list2);
130+
movies.compose(deltaTransformer);
131+
}
132+
133+
static Transformer<List<Movie>, Movie> deltaTransformer = new Transformer<List<Movie>, Movie>() {
134+
@Override
135+
public Observable<Movie> call(Observable<List<Movie>> movieList) {
136+
return movieList
137+
.startWith(new ArrayList<Movie>())
138+
.buffer(2, 1)
139+
.skip(1)
140+
.flatMap(calculateDelta);
141+
}
142+
};
143+
144+
static Func1<List<List<Movie>>, Observable<Movie>> calculateDelta = new Func1<List<List<Movie>>, Observable<Movie>>() {
145+
public Observable<Movie> call(List<List<Movie>> listOfLists) {
146+
if (listOfLists.size() == 1) {
147+
return Observable.from(listOfLists.get(0));
148+
} else {
149+
// diff the two
150+
List<Movie> newList = listOfLists.get(1);
151+
List<Movie> oldList = new ArrayList<Movie>(listOfLists.get(0));
152+
153+
Set<Movie> delta = new LinkedHashSet<Movie>();
154+
delta.addAll(newList);
155+
// remove all that match in old
156+
delta.removeAll(oldList);
157+
158+
// filter oldList to those that aren't in the newList
159+
oldList.removeAll(newList);
160+
161+
// for all left in the oldList we'll create DROP events
162+
for (Movie old : oldList) {
163+
delta.add(new Movie());
164+
}
165+
166+
return Observable.from(delta);
167+
}
168+
};
169+
};
170+
121171
/*
122172
* Most tests are moved into their applicable classes such as [Operator]Tests.java
123173
*/

src/test/java/rx/ObservableTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,7 @@ public void testCompose() {
11101110
Observable.just(1, 2, 3).compose(new Transformer<Integer, String>() {
11111111

11121112
@Override
1113-
public Observable<String> call(Observable<? extends Integer> t1) {
1113+
public Observable<String> call(Observable<Integer> t1) {
11141114
return t1.map(new Func1<Integer, String>() {
11151115

11161116
@Override

0 commit comments

Comments
 (0)