如何正确理解RxJava';什么是团员?

如何正确理解RxJava';什么是团员?,java,functional-programming,rx-java,reactivex,Java,Functional Programming,Rx Java,Reactivex,一般来说,我对RxJava和FP都很陌生。我想写一个代码来连接两个Observables。假设我们有两组整数: [0..4]键选择器作为2的模,给出(键,值)={(0,0)、(1,1)、(0,2),…} [0..9]键选择器作为3的模,给出(键,值)={(0,0),(1,1),(2,2),(0,3),(1,4),…} 我加入他们的步骤如下: 按其键对每个集合进行分组。第一组使用键0和1创建两个组。第二个组创建了三个组,键分别为0、1和2 制作两组组的笛卡尔乘积,总共给出6对组和键:0-0,0

一般来说,我对RxJava和FP都很陌生。我想写一个代码来连接两个
Observable
s。假设我们有两组整数:

  • [0..4]
    键选择器作为
    2的模,给出
    (键,值)={(0,0)、(1,1)、(0,2),…}
  • [0..9]
    键选择器作为
    3的模,给出
    (键,值)={(0,0),(1,1),(2,2),(0,3),(1,4),…}
我加入他们的步骤如下:

  • 按其键对每个集合进行分组。第一组使用键
    0
    1
    创建两个组。第二个组创建了三个组,键分别为
    0
    1
    2
  • 制作两组组的笛卡尔乘积,总共给出6对组和键:
    0-0
    0-1
    0-2
    1-0
    1-1
    1-2
  • 仅过滤两侧键相同的对,只留下
    0-0
    1-1
  • 在每一对中,制作左右两组的笛卡尔乘积
  • 下面是计算笛卡尔积的助手类:

    public class Cross<TLeft, TRight, R> implements Observable.Transformer<TLeft, R> {
        private Observable<TRight>      _right;
        private Func2<TLeft, TRight, R> _resultSelector;
    
        public Cross(Observable<TRight> right, Func2<TLeft, TRight, R> resultSelector) {
            _right = right;
            _resultSelector = resultSelector;
        }
    
        @Override
        public Observable<R> call(Observable<TLeft> left) {
            return left.flatMap(l -> _right.map(r -> _resultSelector.call(l, r)));
        }
    }
    
    如果删除包含
    过滤器的行
    ,则根本不会有结果。正确的输出应该与运行以下命令一样:

    Observable.range(0, 5)
            .compose(new Cross<>(Observable.range(0, 10), ImmutablePair::new))
            .filter(pair -> pair.left % 2 == pair.right % 3)
            .subscribe(System.out::println);
    
    有人能解释一下这种行为吗?非常感谢


    注意:我使用
    org.apache.commons.lang3.tuple.ImmutablePair
    ,以防您怀疑。

    问题是此设置多次尝试订阅组,这是不允许的。您将看到subscribe(System.out::println,Throwable::printStackTrace)的异常重载,建议始终使用此选项。下面是一个固定示例,它允许以另一层ImmutablePair为代价进行重用:

    Func1<Integer, Integer> m2 = i -> i % 2;
    Func1<Integer, Integer> m3 = i -> i % 3;
    
    Observable<ImmutablePair<Integer, Observable<Integer>>> g2 = 
            Observable.range(0, 5).groupBy(m2).map(g -> new ImmutablePair<>(g.getKey(), g.cache()));
    Observable<ImmutablePair<Integer, Observable<Integer>>> g3 = 
            Observable.range(0, 10).groupBy(m3).map(g -> new ImmutablePair<>(g.getKey(), g.cache()));
    
    Observable<ImmutablePair<ImmutablePair<Integer, Observable<Integer>>, ImmutablePair<Integer, Observable<Integer>>>> x1 
    = g2.compose(new Cross<>(g3, ImmutablePair::new));
    
    Observable<ImmutablePair<ImmutablePair<Integer, Observable<Integer>>, ImmutablePair<Integer, Observable<Integer>>>> x2 
    = x1.filter(pair -> pair.left.getKey().equals(pair.right.getKey()));
    
    
    Observable<ImmutablePair<Integer, Integer>> o = x2.flatMap(pair -> 
    pair.left.right.compose(new Cross<>(pair.right.right, ImmutablePair::new)));
    
    o.subscribe(System.out::println, Throwable::printStackTrace);
    
    func1m2=i->i%2;
    Func1 m3=i->i%3;
    可观测g2=
    可观察的.range(0,5).groupBy(m2).map(g->newimmutablepair(g.getKey(),g.cache());
    可观测g3=
    可观察的.range(0,10).groupBy(m3).map(g->newimmutablepair(g.getKey(),g.cache());
    可观测x1
    =g2.compose(新交叉(g3,不可变对::新));
    可观测x2
    =x1.filter(pair->pair.left.getKey().equals(pair.right.getKey());
    可观测o=x2.平面图(对->
    pair.left.right.compose(新十字架(pair.right.right,ImmutablePair::new));
    o、 订阅(System.out::println,Throwable::printStackTrace);
    

    (对于长类型我很抱歉,如果我尝试内联它们而不是使用局部变量,Eclipse会有各种各样的推理问题)

    很酷,它实际上是有效的!我仍然想知道如何知道GroupedObservable是否订阅了多次?始终
    缓存每个组是否是最佳做法?这不容易判断,因为订阅可能隐藏在运营商内部。一种方法是侦听它产生的异常。使用
    cache
    最适合于短序列,因为它无限期地缓存所有内容。有时,通过
    publish(Func1)
    多播可以避免这种情况,但这有其自身的复杂性。
    Observable.range(0, 5)
            .compose(new Cross<>(Observable.range(0, 10), ImmutablePair::new))
            .filter(pair -> pair.left % 2 == pair.right % 3)
            .subscribe(System.out::println);
    
    (0,0)
    (0,3)
    (0,6)
    (0,9)
    (1,1)
    (1,4)
    (1,7)
    (2,0)
    (2,3)
    (2,6)
    (2,9)
    (3,1)
    (3,4)
    (3,7)
    (4,0)
    (4,3)
    (4,6)
    (4,9)
    
    Func1<Integer, Integer> m2 = i -> i % 2;
    Func1<Integer, Integer> m3 = i -> i % 3;
    
    Observable<ImmutablePair<Integer, Observable<Integer>>> g2 = 
            Observable.range(0, 5).groupBy(m2).map(g -> new ImmutablePair<>(g.getKey(), g.cache()));
    Observable<ImmutablePair<Integer, Observable<Integer>>> g3 = 
            Observable.range(0, 10).groupBy(m3).map(g -> new ImmutablePair<>(g.getKey(), g.cache()));
    
    Observable<ImmutablePair<ImmutablePair<Integer, Observable<Integer>>, ImmutablePair<Integer, Observable<Integer>>>> x1 
    = g2.compose(new Cross<>(g3, ImmutablePair::new));
    
    Observable<ImmutablePair<ImmutablePair<Integer, Observable<Integer>>, ImmutablePair<Integer, Observable<Integer>>>> x2 
    = x1.filter(pair -> pair.left.getKey().equals(pair.right.getKey()));
    
    
    Observable<ImmutablePair<Integer, Integer>> o = x2.flatMap(pair -> 
    pair.left.right.compose(new Cross<>(pair.right.right, ImmutablePair::new)));
    
    o.subscribe(System.out::println, Throwable::printStackTrace);