Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将按距离筛选集合的Java 7代码转换为流_Java_Java Stream - Fatal编程技术网

将按距离筛选集合的Java 7代码转换为流

将按距离筛选集合的Java 7代码转换为流,java,java-stream,Java,Java Stream,我有一个工作代码,它接受一个集合,并根据一定的距离应用一个过滤器 例如,列表中的第二个点必须与第一个点至少相距1KM,并且这两个点之间的任何项目都将被删除。 输入已排序 private List<Point> filterByMinimumDistance(List<Point> points, double minDistance) { Point reference = points.get(0); List<Point> filtered

我有一个工作代码,它接受一个集合,并根据一定的距离应用一个过滤器

例如,列表中的第二个点必须与第一个点至少相距1KM,并且这两个点之间的任何项目都将被删除。 输入已排序

private List<Point> filterByMinimumDistance(List<Point> points, double minDistance) {
    Point reference = points.get(0);
    List<Point> filtered = new ArrayList<>();
    filtered.add(reference);
    for (Point point : points) {
        double distance = getDistance(reference, point);
        if (distance >= minDistance) {
            reference = point;
            filtered.add(point);
        }
    }
    return filtered;
}

private double getDistance(Point p1, Point p2) {
    double dx = p1.getX() - p2.getX();
    double dy = p1.getY() - p2.getY();
    return Math.sqrt(dx * dx + dy * dy);
}
private List filterByMinimumDistance(列表点,双精度距离){
点参考=点。获取(0);
List filtered=new ArrayList();
过滤。添加(参考);
用于(点:点){
双距离=getDistance(参考,点);
如果(距离>=距离){
参考=点;
过滤。添加(点);
}
}
返回过滤;
}
专用双getDistance(点p1、点p2){
double dx=p1.getX()-p2.getX();
double dy=p1.getY()-p2.getY();
返回Math.sqrt(dx*dx+dy*dy);
}

到目前为止,我还没能想出一个更奇特的流解决方案来代替这个。任何帮助都将不胜感激。谢谢

您可以为这些点创建自定义收集器:

 private static Collector<Point, ?, List<Point>> customCollector(double minDistance) {

    class Acc {

        private Point reference = null;

        private List<Point> filtered = new ArrayList<>();

        void accumulate(Point elem) {
            if (reference == null) {
                reference = elem;
            }

            double distance = getDistance(reference, elem);

            if (distance >= minDistance) {
                reference = elem;
                filtered.add(elem);
            }
        }

        Acc combine(Acc other) {
            throw new UnsupportedOperationException("Not for parallel");
        }

        List<Point> finisher() {
            return filtered;
        }

        private double getDistance(Point p1, Point p2) {
            double dx = p1.getX() - p2.getX();
            double dy = p1.getY() - p2.getY();
            return Math.sqrt(dx * dx + dy * dy);
        }

    }

    return Collector.of(Acc::new, Acc::accumulate, Acc::combine, Acc::finisher);
}
此外,我可能需要在这里对组合器进行更多的思考,因为我不太确定它是否可以像这样正确实现:

Acc combine(Acc other) {
     filtered.addAll(other.filtered);
     return this;
}

你为什么要这样做?仅仅因为它是“爱好者”…?迈克尔不是因为这个,但它会提高我的技能。我只是想在这里学习一个语义建议:列表中的第一点与其他点不同:它不应该是列表的一部分。将其作为一个单独的参数传入。实际上,在再次读取代码后,如果距离大于最小值,您将分配一个新的
参考。这里的实际算法试图做什么?我认为这不是使用流的好选择。流不应该依赖于以前迭代的副作用。它看起来确实有很多麻烦。不过,我不想为组合器操心,因为并行化会打破要求点按顺序排列的约束。但是谢谢你的回答!我不确定如何实现自定义收集器,但您确实为我指出了正确的方法direction@victorantunes顺序或并行不影响结果的顺序,顺便说一句,一旦我考虑过它,我仍然会添加一个组合器,
Collector
实际上不适合直接实现,而且您需要静态方法,这是一个遗憾。
Acc combine(Acc other) {
     filtered.addAll(other.filtered);
     return this;
}