我有一个常见的Transformer,只需使用给定的Predicate过滤列表:
public class ListFilter<T> implements Observable.Transformer<List<T>, List<T>> {
private final Predicate<T> predicate;
private ListFilter(Predicate<T> predicate) {
this.predicate = predicate;
}
public static <T> Observable.Transformer<List<T>, List<T>> create(Predicate<T> predicate) {
return new ListFilter<>(predicate);
}
@Override
public Observable<List<T>> call(Observable<List<T>> listObservable) {
return listObservable
.flatMap(list -> Observable.from(list)
.filter(predicate::test)
.toList());
}
}
现在我可以使用最少的样板过滤一个项目列表,如下所示:
repository.observeItems() // returns Observable<List<SomeItem>>
.compose(ListFilter.create(item -> /* some filter logic */)
但是我无法解释:
List<? extends Dummy> list = SomeDummyFactory.create();
BehaviorSubject<List<? extends Dummy>> subject = BehaviorSubject.create(list);
// #1 -> ok
BehaviorSubject.create(list)
.compose(ListFilter.create(item -> /* `item` is `Dummy` */)
...
// #2 -> error
subject
.compose(ListFilter.create(item -> /* `item` is `Object` */))
...
// #3 -> ok
subject
.map(any -> any) // do nothing
.compose(ListFilter.create(item -> /* `item` is `Dummy` */))
...
我可以在#2和#3之间看到的唯一区别是Transformer<T, R>
的预期通配符:
Transformer<? super List<? extends Dummy>, ? extends R>
Transformer<? super List<capture of ? extends Dummy>, ? extends List<capture of ? extends Dummy>
所以还有几个问题:
Object
是第二种情况item
的类型(而不是Dummy
)?map
运营商如何帮助它?答案 0 :(得分:0)
这是因为编译器无法重新捕获通配符类型。
在第一种情况下,您可以尝试添加显式泛型。 <Dummy>
和<Object>
都将导致错误。事实类型是(captrue#1 ?) extends Dummy
,由create
的通用返回值推断出来。
在第二种情况下,您的subject
通用类型是List<? extends Dummy>
。 compose
必须接受Transformer<? super List<? extends Dummy>,? extends R>>
,因此create
泛型必须为? extends Dummy
(与情况1相同)。但是在当前编译上下文(当前语句)中,不会捕获通配符类型。编译器无法推断出通用类型,它仅使用Object
,因此会发生错误。
在第三种情况下,map
捕获通配符类型。您可以尝试使用具有通用Observable<R>
返回类型的任何方法,所有这些方法都可以使用。例如.flatMap(d -> Observable.just(d))
。
但是请注意,您的情况3只是一种解决方法。建议的解决方案是让您的ListFilter
的通用名称更灵活。
您应将其定义为ObservableTransformer<List<? extends T>, List<? extends T>>
class ListFilter<T> implements ObservableTransformer<List<? extends T>, List<? extends T>> {
public static <T> ListFilter<T> create(Predicate<T> predicate) {
return new ListFilter<>(predicate);
}
private final Predicate<T> predicate;
private ListFilter(Predicate<T> predicate) {
this.predicate = predicate;
}
@Override
public ObservableSource<List<? extends T>> apply(Observable<List<? extends T>> upstream) {
return upstream
.flatMapSingle(list -> Observable.fromIterable(list)
.filter(predicate::test)
.toList());
}
}