减少 java 中的自定义对象列表
Reduce a list of custom objects in java
我有两个自定义 classes,分别叫做 OrthogonalPoint
和 PolarPoint
。
public class OrthogonalPoint extends AbstractPoint<OrthogonalPoint> {
private double x;
private double y;
// constructor, getters, ...
}
public class PolarPoint extends AbstractPoint<PolarPoint> {
private double rho;
private double theta;
// constructor, getters, ...
}
两者都扩展了一个抽象 class AbstractPoint
.
public abstract class AbstractPoint<PointType extends AbstractPoint<PointType>> {
public abstract double getX();
public abstract double getY();
public final double distance(PointType other) {
// calculate distance between current point and other point
}
}
接下来我有一个classRoute
.
public class Route<T extends AbstractPoint<T>> {
private final List<T> points = new ArrayList<>();
public void appendPoint(T point) {
this.points.add(point);
}
public double routeDistance() {
// calculate total distance
}
}
路线是点的有序数量,其长度定义为序列中点的距离之和。因此,如果路线由三个点(p1、p2 和 p3)组成,则路线的距离为 p1.distance(p2) + p2.distance(p3)
。
在 routeDistance
函数中,我想计算这个距离。我试过类似
public double routeDistance() {
return this.points.stream().reduce(0d, (point, point2) -> point.distance(point2));
}
但是 lambda 函数的主体部分带有红色下划线:
Bad return type in lambda expression: double cannot be converted to T
计算距离的正确方法是什么?我想使用 reduce,但欢迎任何解决方案。
你的问题是你使用reduce的方式不对。 Reduce 不是从流中获取两个元素,而是获取当前累加器和当前元素,并将它们组合起来以获得新的累加器。这里有一个关于 reduce 的好教程:https://www.baeldung.com/java-stream-reduce
这里最简单的方法是不使用流。由于您需要保持每两个点的顺序,只需使用 i 在 0 和 n-1 之间的常规 for 循环遍历所有子路由并求和。
您无法将 Point
减少为 Double
。如果你需要使用 ArrayList
那么你可以 mapToDouble
然后 sum()
(减少的特殊情况):
points.stream().skip(1).mapToDouble(point ->
points.get(points.indexOf(point) - 1).distance(point)).sum();
或
points.stream().limit(points.size() - 1).mapToDouble(point ->
point.distance(points.get(points.indexOf(point) + 1))).sum();
使用 ÌntStream
你可以:
IntStream.range(1, points.size()).mapToDouble(i ->
points.get(i - 1).distance(points.get(i))).sum();
或
IntStream.range(0, points.size() - 1).mapToDouble(i ->
points.get(i).distance(points.get(i + 1))).sum();
我有两个自定义 classes,分别叫做 OrthogonalPoint
和 PolarPoint
。
public class OrthogonalPoint extends AbstractPoint<OrthogonalPoint> {
private double x;
private double y;
// constructor, getters, ...
}
public class PolarPoint extends AbstractPoint<PolarPoint> {
private double rho;
private double theta;
// constructor, getters, ...
}
两者都扩展了一个抽象 class AbstractPoint
.
public abstract class AbstractPoint<PointType extends AbstractPoint<PointType>> {
public abstract double getX();
public abstract double getY();
public final double distance(PointType other) {
// calculate distance between current point and other point
}
}
接下来我有一个classRoute
.
public class Route<T extends AbstractPoint<T>> {
private final List<T> points = new ArrayList<>();
public void appendPoint(T point) {
this.points.add(point);
}
public double routeDistance() {
// calculate total distance
}
}
路线是点的有序数量,其长度定义为序列中点的距离之和。因此,如果路线由三个点(p1、p2 和 p3)组成,则路线的距离为 p1.distance(p2) + p2.distance(p3)
。
在 routeDistance
函数中,我想计算这个距离。我试过类似
public double routeDistance() {
return this.points.stream().reduce(0d, (point, point2) -> point.distance(point2));
}
但是 lambda 函数的主体部分带有红色下划线:
Bad return type in lambda expression: double cannot be converted to T
计算距离的正确方法是什么?我想使用 reduce,但欢迎任何解决方案。
你的问题是你使用reduce的方式不对。 Reduce 不是从流中获取两个元素,而是获取当前累加器和当前元素,并将它们组合起来以获得新的累加器。这里有一个关于 reduce 的好教程:https://www.baeldung.com/java-stream-reduce 这里最简单的方法是不使用流。由于您需要保持每两个点的顺序,只需使用 i 在 0 和 n-1 之间的常规 for 循环遍历所有子路由并求和。
您无法将 Point
减少为 Double
。如果你需要使用 ArrayList
那么你可以 mapToDouble
然后 sum()
(减少的特殊情况):
points.stream().skip(1).mapToDouble(point ->
points.get(points.indexOf(point) - 1).distance(point)).sum();
或
points.stream().limit(points.size() - 1).mapToDouble(point ->
point.distance(points.get(points.indexOf(point) + 1))).sum();
使用 ÌntStream
你可以:
IntStream.range(1, points.size()).mapToDouble(i ->
points.get(i - 1).distance(points.get(i))).sum();
或
IntStream.range(0, points.size() - 1).mapToDouble(i ->
points.get(i).distance(points.get(i + 1))).sum();