如何在Java Streams中使用具有默认值的累加器?

cl25kdpy  于 2023-01-01  发布在  Java
关注(0)|答案(2)|浏览(124)

double类型的Coordinate属性xy类,以及计算从该点到另一个给定点的距离的方法:

public record Coordinate(double x, double y) {
    public double distanceTo(Coordinate point) {
        // implementation
    }
}

我想写一个方法furthestCoordinate来确定给定流中距离点base最远的点,如果流为空,则返回基本身。我写了一个Comparator来比较Coordinate对象和base,但是当给定一个空流时,它抛出一个异常:

static Comparator<Coordinate> WayPointComparator = new Comparator<>() {
    @Override
    public int compare(Coordinate o1, Coordinate o2) {
        return Double.compare(o1.distanceTo(basePoint),o2.distanceTo(basePoint));
    }
};

public static Coordinate furthestCoordinate(Stream<Coordinate> coordinateStream, Coordinate base) {
    basePoint = base; // safes the base to be accessible for the Comparator 

    return coordinateStream.max(WayPointComparator).get();
}

如何使用累加器,每当流中的下一个Coordinate更远时,累加器就会更新,如果流为空,则累加器本身返回'base'?

42fyovps

42fyovps1#

您可以使用Java 8方法Comparator.comparingDouble()来定义基于Coordinate类的方法distanceTo()的比较器。
如果给定流为空,则将Optional.orElse()应用于Stream.max()操作返回的Optional

public static Coordinate furthestCoordinate(Stream<Coordinate> coordinateStream,
                                            Coordinate base) {
    
    return coordinateStream
        .max(Comparator.comparingDouble(base::distanceTo)) // produces Optional<Coordinate>
        .orElse(base);
}
k5ifujac

k5ifujac2#

下面是一种方法:我使用JDK类MathPoint2D.Double
一些数据

List<Point2D> list = new ArrayList<>(
        List.of(
                new Point2D.Double(2.0, 10.0),
        new Point2D.Double(5.0, 6.0),
        new Point2D.Double(4.0, 9.3)));
        
Point2D basePoint = new Point2D.Double(0., 0.);

定义的比较器。

Comparator<Point2D> distanceComp = Comparator
        .comparingDouble(point -> Math.hypot(basePoint.getX() - point.getX(),
                basePoint.getY() - point.getY()));

还有小溪。

list.stream().collect(Collectors.maxBy(distanceComp))
        .ifPresentOrElse(point->System.out.println("Max point is " + point),
                () -> System.out.println("Empty stream"));

印刷品

Max point is Point2D.Double[2.0, 10.0]

collectors.maxBy返回一个Optional<Point2D.Double>。因此使用IfPresentOrElse可以处理答案或报告一个空流。
如果你更喜欢使用自己的类和方法来计算点和距离,那么上面的方法仍然可以很好地工作。
下面是一个函数,用于获取特定basePoint的比较器。

static Function<Point2D, Comparator<Point2D>> getComparator = base -> Comparator
            .comparingDouble(point -> Math.hypot(base.getX() - point.getX(),
                    base.getY() - point.getY()));

然后可以使用streambasePoint调用方法。

public static Point2D furthestCoordinate(Stream<Point2D> coordinateStream,
         Point2D basePoint) {

     return coordinateStream
             .collect(Collectors.maxBy(getComparator.apply(basePoint)))
             .orElse(basePoint);
}
    • 注意:**在本例中,我返回了一个空流的basePoint。但是任何点都可能是有效的答案。您可能只想返回optional,然后使用ifPresent或其他支持的方法来确定如何最好地处理空流。

相关问题