android - 列出将 >10 个改造调用与 rxjava2 组合在一起的子类型转换
问题描述
我想从我的移动 android 应用程序调用我的 API 端点。
我通常使用 zip 运算符来等待最后一个操作完成,但我有 10 多个改造调用要处理,并且我发现输入到 zip 运算符的最大函数是 Function9。
我尝试传递一个可迭代对象,但我对发射器内部的类型有疑问:
@GET("/endpoint/A")
Single<List<A>> getA();
@GET("/endpoint/B")
Single<List<B>> getB();
@GET("/endpoint/C")
Single<List<C>> getC();
....
每个数据类型 A,B,C... 都实现了一个接口 Sample 以便我将 List 传递给 zip 运算符:
List<Single<List<Sample>>> callsList = new ArrayList<>();
callsList.add(apiService.getA()); // error, expected Single<List<Sample>
我试图强制演员,但也没有用
我的目标是使用 iterable 来实现这样的目标:
Single.zip(callsList, new Function<Object[], BundledData>() {
@Override
public BundledData apply(Object[] objects) throws Exception {
return new BundledData(...);
}
})
所以我请求你的帮助:
- 解决类型不兼容问题
- 将正确的数据格式传递给 apply 函数
谢谢
解决方案
你不能这样投。因为Single<List<A>>
不是Single<List<Sample>>
. 这A
是Sample
Single> is not subtype of
Single>` 的子类型。
让我给你一个简单的例子:
List<Number> listA = new ArrayList<>();
List<Integer> listB = new ArrayList<>();
listA = listB; // this line is not valid.
但这是有效的:
Number number = 10;
Integer integer = 20;
number = integer;
因为Integer
是 的子类型Number
。并且 listA = listB;
无效,因为listB
不是 的子类型listA
。
但是您仍然可以投射它,您必须使用Wildcard
.
使用通配符将类似于:
List<? extends Number> listA = new ArrayList<>();
List<? extends Integer> listB = new ArrayList<>();
listA = listB;
现在List<? extends Integer>
是List<? extends Number>
为了使铸造成为可能,我们需要一个共同的父母,List<Number>
并且List<Integer>
是List<?>
共同的父母。
虽然 Integer 是 Number 的子类型,
List<Integer>
但不是 Number 的子类型List<Number>
,实际上这两种类型没有关系。List<Number>
和的共同父项List<Integer>
是List<?>
。为了在这些类之间创建关系,以便代码可以通过 List 的元素访问 Number 的方法,请使用上限通配符:
你的情况是一样的。您需要使用上限通配符。
List< Single< ? extends List< ? extends Sample> > > callsList = new ArrayList<>();
希望这可以帮助你。