如何从数组创建Observable?为何fromArray与just效果相同?
问题解析:为什么Observable.fromArray(double[])和just(arr)效果一致?
哈哈,这个坑我刚接触RxJava的时候也踩过!让我给你捋捋为什么会这样,以及怎么解决~
为什么会出现这个问题?
你遇到的核心原因和Java的可变参数机制以及RxJava fromArray 的设计逻辑有关:
Observable.fromArray接受的是Object...类型的可变参数,它的逻辑是传入多少个参数,就发射多少个元素。- 但当你传入一个基本类型数组(比如
double[])时,Java不会自动把数组里的元素拆分成单个参数传递,而是直接把整个数组对象当作一个Object参数传给方法。 - 而
Observable.just(arr)的逻辑本来就是「把传入的任意对象当作单个元素发射」,所以这两个方法的效果自然完全一致——它们都只会发射那个double[]数组对象,而不是数组里的1、2、3、4。
怎么解决?要逐个发射数组元素的话
这里有几种简单可靠的办法:
方案1:转成包装类型数组
先把 double[] 转换成 Double[](包装类型数组),这样 fromArray 就能识别出数组里的每个元素了:
double[] arr = new double[]{1, 2, 3, 4}; // 将基本类型数组转成包装类型数组 Double[] boxedArr = Arrays.stream(arr).boxed().toArray(Double[]::new); Observable.fromArray(boxedArr) .map(element -> { // 这里的element就是单个的Double值 return element * 2; }) .subscribe(System.out::println);
方案2:手动创建Observable发射元素
如果不想转数组,也可以用 Observable.create 手动遍历数组发射每个元素:
double[] arr = new double[]{1, 2, 3, 4}; Observable.create(emitter -> { for (double num : arr) { emitter.onNext(num); } emitter.onComplete(); }) .map(element -> element + 1) .subscribe(System.out::println);
方案3:转成Iterable集合再发射
把数组转成包装类型的List,再用 Observable.fromIterable 发射:
double[] arr = new double[]{1, 2, 3, 4}; List<Double> numList = Arrays.stream(arr).boxed().collect(Collectors.toList()); Observable.fromIterable(numList) .map(element -> element / 2) .subscribe(System.out::println);
总结
核心关键点就是:基本类型数组在Java可变参数里不会被自动拆包,fromArray 只会把它当作单个对象发射。只要把数组转成包装类型(或者手动处理发射逻辑),就能实现你想要的逐个发射1、2、3、4的效果啦~
内容的提问来源于stack exchange,提问作者Alex Kornakov
相关产品推荐
相关产品推荐

