使用 RxJava 减少自定义对象
Reduce custom object using RxJava
我正在使用 RxJava,我有一个点列表,我想计算每个点之间的距离并求和。
点class看起来像这样
public class Point {
public double x;
public double y;
}
所以我需要同时映射和减少,但我没有找到解决方案。
public Observable<Double> totalDistance(Observable<List<Point>> obs) {
return obs.reduceMap(new ArrayList<Integer>, (list, pointA, pointB) -> distance(pointA, pointB)). ?
}
最有效的方法是什么(或者至少是有效的解决方案)?我应该使用哪个运算符?
举一个更具体的例子,这是我所拥有的和我想要的:
Point a (45, 32)
Point b (56, 75)
Point c (44, 53)
Point d (42, 54)
Point e (42, 55)
a to b = 10m
b to c = 15m
c to d = 25m
d to e = 10m
Result = 60m
实际上我的点是 GPS 位置,我使用 haversine 公式计算两个位置之间的距离。
我使用 observables 是因为要计算的点列表有时会更新。事实上,用户达到的每 x 个点,我都有一个指令要发送。发送指令后,一个新的点列表,直到发出下一条指令。
您可以尝试 buffer and reduce 运算符。例如:
public Observable<Double> totalDistance(Observable<List<Point>> obs) {
return obs.flatMap(points ->
Observable.fromIterable(points)
.buffer(2 /* count */, 1 /* skip */)
/* this emits a list of each two adjacent points from a given list of points. */
.reduce(0.0 /* initial value */, (totalDistance, twoPoints) -> {
// note: calculation may be skipped if the twoPoints list contains less than
// two elements.
final Point pointA = twoPoints.get(0);
final Point pointB = twoPoints.get(1);
return totalDistance + distance(pointA, pointB);
}
).toObservable());
}
您可以使用 map()
方法将 Observable<List<Point>>
的值转换为 Observable<Double>
的值。代码可能如下所示:
public static void main(String[] args) throws Exception {
Point a = new Point(45, 32);
Point b = new Point(56, 75);
Point c = new Point(44, 53);
Point d = new Point(42, 54);
Point e = new Point(42, 55);
List<Point> points = new ArrayList<Point>();
points.add(a);
points.add(b);
points.add(c);
points.add(d);
points.add(e);
Subject<List<Point>> subjectOfListOfPoints = PublishSubject.create();
Observable<List<Point>> observable = subjectOfListOfPoints;
Observable<Double> doubleObservable = observable.map(it -> {
return calculateSumOfDistances(it); });
doubleObservable.subscribe(it -> {
System.out.println("The sum is: "+it);
});
subjectOfListOfPoints.onNext(points);
}
private static double calculateSumOfDistances(List<Point> points) {
List<Double> distances = new ArrayList<Double>();
for (int i=0; i<points.size()-1; i++) {
double distance = distance(points.get(i), points.get(i+1));
System.out.println("Distance is: "+distance);
distances.add(distance);
}
double sum = 0;
for (Double d: distances) {
sum += d;
}
return sum;
}
private static double distance(Point a, Point b) {
return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));
}
这将创建以下输出:
Distance is: 44.384682042344295
Distance is: 25.059928172283335
Distance is: 2.23606797749979
Distance is: 1.0
The sum is: 72.68067819212742
我正在使用 RxJava,我有一个点列表,我想计算每个点之间的距离并求和。
点class看起来像这样
public class Point {
public double x;
public double y;
}
所以我需要同时映射和减少,但我没有找到解决方案。
public Observable<Double> totalDistance(Observable<List<Point>> obs) {
return obs.reduceMap(new ArrayList<Integer>, (list, pointA, pointB) -> distance(pointA, pointB)). ?
}
最有效的方法是什么(或者至少是有效的解决方案)?我应该使用哪个运算符?
举一个更具体的例子,这是我所拥有的和我想要的:
Point a (45, 32)
Point b (56, 75)
Point c (44, 53)
Point d (42, 54)
Point e (42, 55)
a to b = 10m
b to c = 15m
c to d = 25m
d to e = 10m
Result = 60m
实际上我的点是 GPS 位置,我使用 haversine 公式计算两个位置之间的距离。
我使用 observables 是因为要计算的点列表有时会更新。事实上,用户达到的每 x 个点,我都有一个指令要发送。发送指令后,一个新的点列表,直到发出下一条指令。
您可以尝试 buffer and reduce 运算符。例如:
public Observable<Double> totalDistance(Observable<List<Point>> obs) {
return obs.flatMap(points ->
Observable.fromIterable(points)
.buffer(2 /* count */, 1 /* skip */)
/* this emits a list of each two adjacent points from a given list of points. */
.reduce(0.0 /* initial value */, (totalDistance, twoPoints) -> {
// note: calculation may be skipped if the twoPoints list contains less than
// two elements.
final Point pointA = twoPoints.get(0);
final Point pointB = twoPoints.get(1);
return totalDistance + distance(pointA, pointB);
}
).toObservable());
}
您可以使用 map()
方法将 Observable<List<Point>>
的值转换为 Observable<Double>
的值。代码可能如下所示:
public static void main(String[] args) throws Exception {
Point a = new Point(45, 32);
Point b = new Point(56, 75);
Point c = new Point(44, 53);
Point d = new Point(42, 54);
Point e = new Point(42, 55);
List<Point> points = new ArrayList<Point>();
points.add(a);
points.add(b);
points.add(c);
points.add(d);
points.add(e);
Subject<List<Point>> subjectOfListOfPoints = PublishSubject.create();
Observable<List<Point>> observable = subjectOfListOfPoints;
Observable<Double> doubleObservable = observable.map(it -> {
return calculateSumOfDistances(it); });
doubleObservable.subscribe(it -> {
System.out.println("The sum is: "+it);
});
subjectOfListOfPoints.onNext(points);
}
private static double calculateSumOfDistances(List<Point> points) {
List<Double> distances = new ArrayList<Double>();
for (int i=0; i<points.size()-1; i++) {
double distance = distance(points.get(i), points.get(i+1));
System.out.println("Distance is: "+distance);
distances.add(distance);
}
double sum = 0;
for (Double d: distances) {
sum += d;
}
return sum;
}
private static double distance(Point a, Point b) {
return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));
}
这将创建以下输出:
Distance is: 44.384682042344295
Distance is: 25.059928172283335
Distance is: 2.23606797749979
Distance is: 1.0
The sum is: 72.68067819212742