我的功能是获取一组点,检查它们与给定点的距离,并返回一个最接近点的有序集。如果2点与给定点的距离相同,则两者都会保留,没问题。
我使用该函数从2D坐标中选择任意用户给定点的k个最近点。这只是从有序集中挑选前k个点的问题。
现在它是这样的,我想对于每个添加的点(不好),一次又一次地调用距离计算
import java.awt.geom.Point2D;
import java.util.Comparator;
/**
* This comparator sorts two points by destination distance.
*/
public class NearestComparator implements Comparator<Point2D> {
/** The point to be reached. */
private Point2D destination;
/**
* Instantiates a new comparator that sorts points by destination distance, descendant.
*
* @param destination the point to reach
*/
public NearestComparator(Point2D destination) {
this.destination = destination;
}
/**
* Sort two points by destination distance, descendant.
*
* @param p1 the first point
* @param p2 the second point
*/
@Override
public int compare(Point2D p1, Point2D p2) {
double p1_distance = p1.distance(destination);
double p2_distance = p2.distance(destination);
return (p1_distance < p2_distance) ? -1 : ((p1_distance > p2_distance) ? 1 : 0);
}
}
现在的排序代码就像这样
private List<Point2D> getSendOrder(Point2D destination) {
LinkedList<Point2D> sendOrderList = new LinkedList<Point2D>();
sendOrderList.add(myPosition);
Iterator<Point2D> keyIter = neighborLinks.keySet().iterator();
while (keyIter.hasNext()) {
sendOrderList.add(keyIter.next());
}
// sort list by distance from destination
Collections.sort(sendOrderList, new NearestComparator(destination));
return sendOrderList;
}
标准库中是否有数据结构允许我添加一个与其自己的类无关的固定“优先级”的元素?我的意思是,(priority 1, Object ref x)
,(priority 2, Object ref y)
,(priority 1, Object ref z)
等等。
我需要尽可能快地生成尽可能少的垃圾。它用于图中的路由算法。无需快速访问有序集的中间,只需要顶部(最低距离,最高优先级)。但是,能够以有效的方式删除最高优先级元素非常重要。
正如您所看到的,只要我以正确的方式获得一个列表(第一个元素具有更高的优先级等),我就不需要在返回的结果中保留优先级信息。
答案 0 :(得分:0)
我已经想过使用Map.Entry包裹距离,如果你需要,这也允许深度复制。
这是一个完整的例子
package sandbox;
import java.awt.geom.Point2D;
import java.util.AbstractMap.SimpleEntry;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
public class Node {
private Point2D myPosition;
private Map<Point2D, Node> neighborLinks;
public class NearestComparator implements Comparator<Entry> {
@Override
public int compare(Entry e1, Entry e2) {
return Double.compare((Double) e1.getValue(), (Double) e2.getValue());
}
}
public List<Point2D> getSendOrder(Point2D destination) {
LinkedList<Entry> sendOrderList = new LinkedList<>();
Entry<Point2D, Double> pointWithDist;
// calculate distance from destination and wrap it using an Entry
pointWithDist = new SimpleEntry<>(myPosition, myPosition.distance(destination));
sendOrderList.add(pointWithDist);
for (Point2D otherPoint : neighborLinks.keySet()) {
pointWithDist = new SimpleEntry<>(otherPoint, otherPoint.distance(destination));
sendOrderList.add(pointWithDist);
}
// sort list by distance from destination
Collections.sort(sendOrderList, new NearestComparator());
// print all the list (debug)
System.out.println(Arrays.toString(sendOrderList.toArray()));
// unwrap and deep copy
LinkedList<Point2D> copiedList = new LinkedList<>();
Point2D pointToCopy, copiedPoint;
for (Entry entry : sendOrderList) {
pointToCopy = (Point2D) entry.getKey();
copiedPoint = new Point2D.Double(pointToCopy.getX(), pointToCopy.getY());
copiedList.add(copiedPoint);
}
return copiedList;
}
public Node(Point2D myPosition, Map<Point2D, Node> neighborLinks) {
this.myPosition = myPosition;
this.neighborLinks = neighborLinks;
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Map<Point2D, Node> neighborLinks = new HashMap<>();
Random rand = new Random();
double x, y, max = 5;
for (int i = 0; i < 10; ++i) {
x = rand.nextDouble() * max;
y = rand.nextDouble() * max;
neighborLinks.put(new Point2D.Double(x, y), null);
}
Point2D nodePos = new Point2D.Double();
Node myNode = new Node(nodePos, neighborLinks);
Point2D destination = new Point2D.Double();
myNode.getSendOrder(destination);
}
}