Rxjava(变换类)-GroupBy

将一个Observable分拆为一些Observables集合,它们中的每一个发射原始Observable的一个 子序列,哪个数据项由哪一个Observable发射是由一个函数判定 的,这个函数给每一项指定一个Key,Key相同的数据会被同一个Observable发射.


demo

Observable.range(1, 8).groupBy(new Func1<Integer, String>() {
            @Override
            public String call(Integer integer) {
                return (integer % 2 == 0) ? "偶数组" : "奇数组";
            }
        }).subscribe(new Action1<GroupedObservable<String, Integer>>() {
            @Override
            public void call(final GroupedObservable<String, Integer> stringIntegerGroupedObservable) {
                System.out.println("group name:" + stringIntegerGroupedObservable.getKey());
                if (stringIntegerGroupedObservable.getKey().equalsIgnoreCase("奇数组"))
                    stringIntegerGroupedObservable.subscribe(new Action1<Integer>() {
                        @Override
                        public void call(Integer integer) {
                            System.out.println(stringIntegerGroupedObservable.getKey() + "'member: " + integer);
                        }
                    });
            }
        });
输出:

group name:奇数组
奇数组'member: 1
group name:偶数组
奇数组'member: 3
奇数组'member: 5
奇数组'member: 7


这里我们分成两组,并输出了其中一组的成员。下面我们看一下groupBy函数

    public final <K> Observable<GroupedObservable<K, T>> groupBy(final Func1<? super T, ? extends K> keySelector) {
        return lift(new OperatorGroupBy<T, K, T>(keySelector));
    }
创建了一个OperatorGroupBy,传递keySelector用来区分分组

 public OperatorGroupBy(Func1<? super T, ? extends K> keySelector) {
        this(keySelector, (Func1)UtilityFunctions.<T>identity(), RxRingBuffer.SIZE, false, null);
    }
   public OperatorGroupBy(Func1<? super T, ? extends K> keySelector, Func1<? super T, ? extends V> valueSelector, int bufferSize, boolean delayError, Func1<Action1<K>, Map<K, Object>> mapFactory) {
        this.keySelector = keySelector;
        this.valueSelector = valueSelector;
        this.bufferSize = bufferSize;
        this.delayError = delayError;
        this.mapFactory = mapFactory;
    }
groupBy函数创建了一个Observable,Observable的onSubscribe是OnSubscribeLift ,OnSubscribeLift的operator是OperatorGroupBy

在后面subscribe的时候OnSubscribeLift的call

 public void call(Subscriber<? super R> o) {
        try {
            Subscriber<? super T> st = RxJavaHooks.onObservableLift(operator).call(o);
            try {
                // new Subscriber created and being subscribed with so 'onStart' it
                st.onStart();
                parent.call(st);
            } catch (Throwable e) {
                // localized capture of errors rather than it skipping all operators
                // and ending up in the try/catch of the subscribe method which then
                // prevents onErrorResumeNext and other similar approaches to error handling
                Exceptions.throwIfFatal(e);
                st.onError(e);
            }
        } catch (Throwable e) {
            Exceptions.throwIfFatal(e);
            // if the lift function failed all we can do is pass the error to the final Subscriber
            // as we don't have the operator available to us
            o.onError(e);
        }
    }

这里会调用OperatorGroupBy的call

 public Subscriber<? super T> call(Subscriber<? super GroupedObservable<K, V>> child) {
        final GroupBySubscriber<T, K, V> parent; // NOPMD
        try {
            parent = new GroupBySubscriber<T, K, V>(child, keySelector, valueSelector, bufferSize, delayError, mapFactory);
        } catch (Throwable ex) {
            //Can reach here because mapFactory.call() may throw in constructor of GroupBySubscriber
            Exceptions.throwOrReport(ex, child);
            Subscriber<? super T> parent2 = Subscribers.empty();
            parent2.unsubscribe();
            return parent2;
        }

        child.add(Subscriptions.create(new Action0() {
            @Override
            public void call() {
                parent.cancel();
            }
        }));

        child.setProducer(parent.producer);

        return parent;
    }

这里会创建一个GroupBySubscriber的订阅者,child是demo中最初的订阅者

public GroupBySubscriber(Subscriber<? super GroupedObservable<K, V>> actual, Func1<? super T, ? extends K> keySelector,
                Func1<? super T, ? extends V> valueSelector, int bufferSize, boolean delayError,
                Func1<Action1<K>, Map<K, Object>> mapFactory) {
            this.actual = actual;
            this.keySelector = keySelector;
            this.valueSelector = valueSelector;
            this.bufferSize = bufferSize;
            this.delayError = delayError;
            this.queue = new ConcurrentLinkedQueue<GroupedObservable<K, V>>();
            this.s = new ProducerArbiter();
            this.s.request(bufferSize);
            this.producer = new GroupByProducer(this);
            this.cancelled = new AtomicBoolean();
            this.requested = new AtomicLong();
            this.groupCount = new AtomicInteger(1);
            this.wip = new AtomicInteger();
            if (mapFactory == null) {
                this.groups = new ConcurrentHashMap<Object, GroupedUnicast<K, V>>();
                this.evictedKeys = null;
            } else {
                this.evictedKeys = new ConcurrentLinkedQueue<K>();
                this.groups = createMap(mapFactory, new EvictionAction<K>(evictedKeys));
            }
        }
创建一个producer,类型是GroupByProducer,bufferSize是128,这里调用request最终会把requested变量设置为128
回到call, 调用

child.setProducer(parent.producer);
最终会调用producer的request,这里没做什么事,最终把刚生成的GroupBySubscriber返回

回到OnSubscribeLift的call,最终调用OnSubscribeRange

最终会调用RangeProducer的request

 public void request(long requestedAmount) {
            if (get() == Long.MAX_VALUE) {
                // already started with fast-path
                return;
            }
            if (requestedAmount == Long.MAX_VALUE && compareAndSet(0L, Long.MAX_VALUE)) {
                // fast-path without backpressure
                fastPath();
            } else if (requestedAmount > 0L) {
                long c = BackpressureUtils.getAndAddRequest(this, requestedAmount);
                if (c == 0L) {
                    // backpressure is requested
                    slowPath(requestedAmount);
                }
            }
        }
这里requestedAmount是128,走slowPath

void slowPath(long requestedAmount) {
            long emitted = 0L;
            long endIndex = endOfRange + 1L;
            long index = currentIndex;

            final Subscriber<? super Integer> childSubscriber = this.childSubscriber;

            for (;;) {

                while (emitted != requestedAmount && index != endIndex) {
                    if (childSubscriber.isUnsubscribed()) {
                        return;
                    }

                    childSubscriber.onNext((int)index);

                    index++;
                    emitted++;
                }

                if (childSubscriber.isUnsubscribed()) {
                    return;
                }

                if (index == endIndex) {
                    childSubscriber.onCompleted();
                    return;
                }

                requestedAmount = get();

                if (requestedAmount == emitted) {
                    currentIndex = index;
                    requestedAmount = addAndGet(-emitted);
                    if (requestedAmount == 0L) {
                        break;
                    }
                    emitted = 0L;
                }
            }
        }

这里的childSubscriber是GroupBySubscriber,调用它的onNext

public void onNext(T t) {
            if (done) {
                return;
            }

            final Queue<GroupedObservable<K, V>> q = this.queue;
            final Subscriber<? super GroupedObservable<K, V>> a = this.actual;

            K key;
            try {
                key = keySelector.call(t);
            } catch (Throwable ex) {
                unsubscribe();
                errorAll(a, q, ex);
                return;
            }

            boolean notNew = true;
            Object mapKey = key != null ? key : NULL_KEY;
            GroupedUnicast<K, V> group = groups.get(mapKey);
            if (group == null) {
                // if the main has been cancelled, stop creating groups
                // and skip this value
                if (!cancelled.get()) {
                    group = GroupedUnicast.createWith(key, bufferSize, this, delayError);
                    groups.put(mapKey, group);

                    groupCount.getAndIncrement();

                    notNew = false;
                    q.offer(group);
                    drain();
                } else {
                    return;
                }
            }

            V v;
            try {
                v = valueSelector.call(t);
            } catch (Throwable ex) {
                unsubscribe();
                errorAll(a, q, ex);
                return;
            }

            group.onNext(v);

            if (evictedKeys != null) {
                K evictedKey;
                while ((evictedKey = evictedKeys.poll()) != null) {
                    GroupedUnicast<K, V> g = groups.get(evictedKey);
                    if (g != null) {
                        g.onComplete();
                    }
                }
            }

            if (notNew) {
                s.request(1);
            }
        }

keySelector是我们代码中设置的分组依据

获取到当前key所属的组之后,判断当前是否已经添加过改组,没有则创建相应的GroupedUnicast添加到groups,并添加到队列

然后调用drain方法

void drain() {
            if (wip.getAndIncrement() != 0) {
                return;
            }

            int missed = 1;

            final Queue<GroupedObservable<K, V>> q = this.queue;
            final Subscriber<? super GroupedObservable<K, V>> a = this.actual;

            for (;;) {

                if (checkTerminated(done, q.isEmpty(), a, q)) {
                    return;
                }

                long r = requested.get();
                long e = 0L;

                while (e != r) {
                    boolean d = done;

                    GroupedObservable<K, V> t = q.poll();

                    boolean empty = t == null;

                    if (checkTerminated(d, empty, a, q)) {
                        return;
                    }

                    if (empty) {
                        break;
                    }

                    a.onNext(t);

                    e++;
                }

                if (e != 0L) {
                    if (r != Long.MAX_VALUE) {
                        BackpressureUtils.produced(requested, e);
                    }
                    s.request(e);
                }

                missed = wip.addAndGet(-missed);
                if (missed == 0) {
                    break;
                }
            }
        }
这里队列已经不为空

 a.onNext(t)
这里最终会调用到我们的订阅者
回到前面onNext,接着调用

 v = valueSelector.call(t);
这里查看是否会对值做变换,我们这里没有

接着调用

group.onNext(v);
        public void onNext(T t) {
            state.onNext(t);
        }
 public void onNext(T t) {
            if (t == null) {
                error = new NullPointerException();
                done = true;
            } else {
                queue.offer(NotificationLite.next(t));
            }
            drain();
        }

这里入队列,然后调用drain,最终会调用到我们为这个组添加的订阅者


然后看下demo中

stringIntegerGroupedObservable.subscribe(new Action1<Integer>() {
                        @Override
                        public void call(Integer integer) {
                            System.out.println(stringIntegerGroupedObservable.getKey() + "'member: " + integer);
                        }
                    });
这里最终会调用到OperatorGroupBy的State的call

public void call(Subscriber<? super T> s) {
            if (once.compareAndSet(false, true)) {
                s.add(this);
                s.setProducer(this);
                actual.lazySet(s);
                drain();
            } else {
                s.onError(new IllegalStateException("Only one Subscriber allowed!"));
            }
        }
这里会设置actual,它在前面的drain方法中会使用到











  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值