如何在RxJava中返回聚合-collect()是正确的方法吗?
我有一个Observable,它发出“昂贵”的值来获取(想想慢速网络),我需要处理单个项目以及一些聚合。我想用一个如何在RxJava中返回聚合-collect()是正确的方法吗?,java,rx-java,reactive-programming,Java,Rx Java,Reactive Programming,我有一个Observable,它发出“昂贵”的值来获取(想想慢速网络),我需要处理单个项目以及一些聚合。我想用一个订阅(…)就可以了。我希望Observable只为所有订户发出一次其值 我创建了一个示例来演示我的困境。在本例中,我使用一个集合作为数据源—不要因此而分心。多次运行一个集合是“便宜的”-但这不是我的用例,所以这里不要放大集合的使用;-) 我有一个简单的课程: public class Lego { public final String color; public fina
订阅(…)
就可以了。我希望Observable只为所有订户发出一次其值
我创建了一个示例来演示我的困境。在本例中,我使用一个集合作为数据源—不要因此而分心。多次运行一个集合是“便宜的”-但这不是我的用例,所以这里不要放大集合的使用;-)
我有一个简单的课程:
public class Lego {
public final String color;
public final String shape;
public final String size;
public final int nippels;
public Lego(final String color, final String shape, final String size, final int nippels) {
this.color = color;
this.shape = shape;
this.size = size;
this.nippels = nippels;
}
@Override
public String toString() {
return String.format("Color: %s, Shape: %s, Size: %s, Nipples: %d",this.color,this.shape,this.size,this.nippels);
}
}
以及这些对象的集合:
public Observable<Lego> getLegoSample() {
Collection<Lego> result = new ArrayList<Lego>();
result.add(new Lego("red", "cube", "xl", 6));
result.add(new Lego("blue", "box", "s", 2));
result.add(new Lego("green", "cube", "l", 4));
result.add(new Lego("yellow", "odd", "m", 3));
result.add(new Lego("red", "sphere", "xs", 0));
result.add(new Lego("blue", "box", "xl", 8));
result.add(new Lego("green", "odd", "s", 1));
result.add(new Lego("green", "odd", "m", 1));
result.add(new Lego("green", "odd", "l", 1));
result.add(new Lego("yellow", "odd", "m", 3));
result.add(new Lego("blue", "box", "m", 4));
result.add(new Lego("green", "cube", "l", 4));
result.add(new Lego("yellow", "sphere", "m", 3));
result.add(new Lego("red", "sphere", "xl", 7));
result.add(new Lego("blue", "cube", "xl", 8));
result.add(new Lego("green", "odd", "s", 1));
result.add(new Lego("yellow", "box", "s", 1));
result.add(new Lego("yellow", "sphere", "l", 1));
Observable<Lego> observable = Observable.from(result);
return observable;
}
2问题s:
更新(9月4日): 读报纸有帮助(我的坏习惯)。我看错了方向。为了让所有潜在订户只发射一次可观测数据,它需要是a,一个可观测数据的子类。这可以通过使用任何可观察到的数据来实现 可连接的可观察对象在其方法被调用之前不会发出任何值 因此,我的代码如下所示:
ConnectableObservable co = getLegoSample().publish();
co.subscribe();
co.collect(new HashMap<String,Integer>(), new Action2<Map<String,Integer>,Lego>(){
@Override
public void call(Map<String, Integer> t1, Lego t2) {
if (t1.containsKey(t2.color)) {
t1.put(t2.color,(t1.get(t2.color).intValue()+1));
} else {
t1.put(t2.color, 1);
}
}}).subscribe();
co.count().subscribe();
co.map(LegotoNipples).sum().subscribe();
co.connect();
ConnectableObservable co=getLegoSample().publish();
公司认购(;
co.collect(新的HashMap(),新的Action2()){
@凌驾
公共无效呼叫(地图t1、乐高t2){
if(t1.容器Y(t2.颜色)){
t1.put(t2.color,(t1.get(t2.color.intValue()+1));
}否则{
t1.put(t2.color,1);
}
}}).subscribe();
co.count().subscribe();
co.map(LegotoNipples.sum().subscribe();
co.connect();
对于聚合,仍然是collect()
的问题,最终,当使用不同的调度程序时,如何最好地进行编排(但这是有问题的)
(是的,我一直在使用Java<8) 您还可以使用
Observable.groupBy
进行聚合。考虑这个样本:
Observable<NamedCount<String>> countStream =
getLegoSample()
.groupBy(Lego::getColor)
.flatMap(obs -> obs.count().map(count -> new NamedCount<>(obs.getKey(), count)))
产生以下输出
NamedCount{name=red, count=3}
NamedCount{name=green, count=6}
NamedCount{name=blue, count=4}
NamedCount{name=yellow, count=5}
将传递的thr函数更改为
Observable.groupBy()
可以获得其他聚合(按形状、大小等计数)有趣。我会试试看。现在需要找出Lego::getColor的Java6等价物这是方法引用-java 8之前的等价物是new Func1(){@Override public String call(Lego-Lego){return Lego.getColor();}}
,或者可以用lambdasLego->Lego.getColor()重写它
public class NamedCount<T> {
private final T name;
private final int count;
public NamedCount(T name, int count) {
this.name = name;
this.count = count;
}
public T getName() {
return name;
}
public int getCount() {
return count;
}
}
countStream.subscribe(System.out::println);
NamedCount{name=red, count=3}
NamedCount{name=green, count=6}
NamedCount{name=blue, count=4}
NamedCount{name=yellow, count=5}