列出用于结合> 10个改造调用和rxjava2

时间:2018-07-17 08:03:41

标签: android list retrofit2 rx-java2

我想从我的移动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>

我试图强制演员阵容,但都没有起作用

我的目标是使用迭代器来实现以下目的:

Single.zip(callsList, new Function<Object[], BundledData>() {
        @Override
        public BundledData apply(Object[] objects) throws Exception {
            return new BundledData(...);
        }
    })

所以我正在寻求您的帮助:

  • 解决类型不兼容
  • 将正确的数据格式传递给apply函数

谢谢

1 个答案:

答案 0 :(得分:2)

您不能以这种方式进行投射。因为Single<List<A>>不是Single<List<Sample>>的子类型。这里的ASample的子类型,但是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;

因为IntegerNumber的子类型。并且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<?>是公共父级。

这在official doc

中有很好的解释

enter image description here

  

尽管Integer是Number的子类型,List<Integer>不是List<Number>的子类型,实际上,这两种类型无关。 List<Number>List<Integer>的共同父级是List<?>

     

为了在这些类之间创建关系,使   代码可以通过List的元素访问Number的方法,使用   上限通配符:

您的情况是相同的。您需要使用上限通配符。

List< Single< ? extends List< ? extends Sample> > > callsList = new ArrayList<>();

希望这对您有所帮助。