【问题标题】:Understand Observable.fromArray in RxJava理解 RxJava 中的 Observable.fromArray
【发布时间】:2021-04-03 22:59:40
【问题描述】:

我正在尝试学习不同的 RxJava 运算符。我对 Observable.just 和 Observable.fromArray() 以及它们如何发出 Observables 有点困惑。

单个整数工作正常,但为了更好地理解差异,我尝试使用数组。我有下面的代码,它适用于单个整数,但是当我传递数组时,它说一些编译错误,我不明白如何解决。

单个整数的代码

Observable.fromArray(10,20,30).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                Util.d("Emit Integers : "+ it)
            })

输出是:

Emit Integers : 10
Emit Integers : 20
Emit Integers : 30

现在要从某个列表中发出整数,我尝试以下代码:

var numbers = arrayOf<Int>(1, 2, 3)
Observable.fromArray(numbers).subscribeOn(Schedulers.io())
       .observeOn(AndroidSchedulers.mainThread())
        .subscribe({
            Util.d("Emit Integers: "+ it)
         })

我得到的输出是

Emit Integers: [Ljava.lang.Integer;@8a69c02

我期望的是将数组的每一项返回为 Observable。 fromArray() 不可能吗?如果没有,Observable.fromArray()有什么用

【问题讨论】:

    标签: observable rx-java


    【解决方案1】:

    根据他们的doc fromArray() 只支持引用数组。但是在 kotlin 中 arrayOf&lt;Int&gt;() 返回 Array 对象。如果我们在fromArray() 方法中放置一个kotlin Array 对象,它会创建Array 对象的数组(在java 中,它将是Array[])。所以订阅Observable 后返回Array 的对象。 但是如果我们将项目放入fromArray() 方法中,它将创建Int 的数组。所以订阅后它会返回Int。 如果你想迭代任何可变迭代,那么你可以试试Observable.fromIterable()

    【讨论】:

    • 现在说得通了。奇怪的是它在 java 中有效,但在 kotlin 中无效。你解释得很好。
    • 虽然这个github.com/ReactiveX/RxJava/wiki/Creating-Observables#fromarray 它说RxJava does not support primitive arrays, only (generic) reference arrays.
    • 对不起,我错误地交换了支持的类型。但想法接近于此。我正在更新答案。
    【解决方案2】:
            val arr = arrayOf("111", "222")
    
            Observable.fromArray(*arr)
                .subscribe {
                    Log.d("test", "$it")
                }
    
            Observable.fromIterable(arr.asIterable())
                .subscribe {
                    Log.d("test", "$it")
                }
    

    【讨论】:

    • 请尝试添加一些解释。
    • 我们使用扩展运算符 ( * ) 将数组元素作为参数传递
    【解决方案3】:

    我能够使用 fromIterable 运算符解决它

    Observable.fromIterable(listOf(1,2,3))
                    .subscribe({
                        Util.d("Emit Integers from list: "+ it)
                    })
    

    并在此处的帖子中进行了总结:http://kukroid.com/2019/12/28/difference-between-observable-just-and-observable-fromarray/

    【讨论】:

      【解决方案4】:

      简而言之,arrayOf(10, 20, 30) 创建了一个 int[],它与 fromArray 要求的 Object[] 不兼容,因此它将整个 int[] 数组作为单个项目发出。 RxJava 不支持原始数组源。如果您无法将 int[] 数组转换为 Integer[] 数组,则可以执行 indexed-for 等效操作:

       var a = arrayOf(10, 20, 30)
      
       Observable.range(0, a.size)
                 .map { index -> a[index] }
                 .subscribe { println(it) }
      

      【讨论】:

        【解决方案5】:
        /**
         * Converts an Array into an ObservableSource that emits the items in the Array.
         * <p>
         * <img width="640" height="315" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/from.png" alt="">
         * <dl>
         *  <dt><b>Scheduler:</b></dt>
         *  <dd>{@code fromArray} does not operate by default on a particular {@link Scheduler}.</dd>
         * </dl>
         *
         * @param items
         *            the array of elements
         * @param <T>
         *            the type of items in the Array and the type of items to be emitted by the resulting ObservableSource
         * @return an Observable that emits each item in the source Array
         * @see <a href="http://reactivex.io/documentation/operators/from.html">ReactiveX operators documentation: From</a>
         */
        
        @CheckReturnValue
        @SchedulerSupport(SchedulerSupport.NONE)
        @NonNull
        public static <T> Observable<T> fromArray(T... items) {
            ObjectHelper.requireNonNull(items, "items is null");
            if (items.length == 0) {
                return empty();
            }
            if (items.length == 1) {
                return just(items[0]);
            }
            return RxJavaPlugins.onAssembly(new ObservableFromArray<T>(items));
        }
        

        fromArray 接受项目。这里(10, 20, 30) != arrayOf&lt;Int&gt;(1, 2, 3) 两个不同的东西。 10, 20 ,30 将其自身作为一个项目,而 numbers 将其自身作为一个项目。我希望你能理解我试图解释的内容。

        【讨论】:

          猜你喜欢
          • 2019-07-05
          • 2014-09-15
          • 2016-02-27
          • 2023-03-18
          • 2023-03-22
          • 2018-03-31
          • 1970-01-01
          • 2014-08-06
          • 1970-01-01
          相关资源
          最近更新 更多