Java 对从哈希集创建的数组进行排序的最有效方法

Java 对从哈希集创建的数组进行排序的最有效方法,java,arrays,hashset,Java,Arrays,Hashset,我正在研究一种方法,在给定GPS坐标的某个半径内创建一组公交站点,然后将该集合转换为一个数组 我想根据相对于GPS坐标的距离来订购此阵列,哪种方法最有效 public Stop[] possibleStops(GPSCoordinate spot) { Set<Stop> viableBusStops = new HashSet<Stop>(); for(Map.Entry<String, Stop> stopEntry : stops.ent

我正在研究一种方法,在给定GPS坐标的某个半径内创建一组公交站点,然后将该集合转换为一个数组

我想根据相对于GPS坐标的距离来订购此阵列,哪种方法最有效

public Stop[] possibleStops(GPSCoordinate spot) {
    Set<Stop> viableBusStops = new HashSet<Stop>();
    for(Map.Entry<String, Stop> stopEntry : stops.entrySet()) {
        Stop applicant = stopEntry.getValue();
        Double distance = spot.distance(applicant.getGPSCoordinate());
        if (distance<=threshold) {
            viableBusStops.add(applicant);
        }
    }
    Stop[] stopList = viableBusStops.toArray(new Stop[0])
    return stopList;
}
public Stop[]可能的站点(GPSCoordinate spot){
Set viableBusStops=new HashSet();
对于(Map.Entry stopEntry:stops.entrySet()){
停止申请者=stopEntry.getValue();
双距离=点距离(applicator.getGPSCoordinate());

如果(距离最可能的方法是:

注意:您可能应该将计算出的距离缓存到
停止
对象(或包装器)内的所需位置,以便在将对象与
比较器


你也可以考虑使用<代码> TreMaP < /C> >代码> >键>代码>值>代码>是<代码>停止>代码>,然后提取值并将它们转换成数组。

< p>构建一个map /<代码>,将停止点映射到它们与点的距离。然后根据距离排序条目。

用比较器测量树集

public class SortByDistance implements Comparator<Distance>{
        public int compare(Distance d1, Distance d2) {
            return d1.getLength().compareTo(d2.getLength());
        }
    }

TreeSet<Distance> names = new TreeSet<Distance>(new SortByDistance());
公共类SortByDistance实现了Comparator{
公共整数比较(距离d1,距离d2){
返回d1.getLength().compareTo(d2.getLength());
}
}
树集名称=新树集(new SortByDistance());

您可以使用Java 8流:

public Stop[] possibleStops(GPSCoordinate spot) {
    // dummies
    Map<String, Stop> stops = new HashMap<>();
    double threshold = 10.0;

    Stop[] filteredSortedStops = stops.values().stream()
            .collect(Collectors.toMap((stop) -> stop,
                    (stop) -> spot.distance(stop.getGPSCoordinate())))
            .entrySet()
            .stream()
            .filter((entry) -> entry.getValue() <= threshold)
            .sorted(Comparator.comparingDouble(Map.Entry::getValue))
            .map(Map.Entry::getKey)
            .toArray(Stop[]::new);

    return filteredSortedStops;
}
public Stop[]可能的站点(GPSCoordinate spot){
//假人
Map stops=newhashmap();
双阈值=10.0;
Stop[]filteredSortedStops=stops.values().stream()
.collect(收集器).toMap((停止)->停止,
(stop)->spot.distance(stop.getGPSCoordinate()))
.entrySet()
.stream()
.filter((entry)->entry.getValue()试试这个

public Stop[] possibleStops(GPSCoordinate spot) {
    return stops.values().stream()
        .map(stop -> new AbstractMap.SimpleEntry<>(
            spot.distance(stop.getGPSCoordinate()), stop))
        .filter(e -> e.getKey() <= threshold)
        .sorted(Comparator.comparing(e -> e.getKey()))
        .map(Entry::getValue)
        .toArray(Stop[]::new);
}
public Stop[]可能的站点(GPSCoordinate spot){
返回stops.values().stream()
.map(停止->新建AbstractMap.SimpleEntry(
点距离(stop.getGPSCoordinate()),stop)
.filter(e->e.getKey()e.getKey())
.map(条目::getValue)
.toArray(停止[]::新建);
}

如果您声明了一个函数,该函数以公交车站为参数并返回其到站点的距离,那么您可以创建一个比较器,根据该函数返回的公交车站到站点的距离对公交车站进行排序

然而,为了完成其工作,比较器可能会多次访问一个给定的元素,这意味着对于给定的公交车站,其到站点的距离可能会被计算多次

避免这种情况的一种方法是使用一种称为的技术。本质上,这意味着使用某种缓存来记住以前为函数计算的值

您可以使用以下帮助器方法实现备忘录化:

static <T, R> Function<T, R> memoize(Function<T, R> function) {
    Map<T, R> cache = new HashMap<>();
    return t -> cache.computeIfAbsent(t, function);
}
静态函数记忆(函数){
映射缓存=新的HashMap();
返回t->cache.computeFabSent(t,函数);
}
现在,为了解决您的问题,您可以创建一个记忆函数,该函数将一个公交车站作为参数,并返回其到站点的距离:

Function<Stop, Double> distanceToSpot = memoize(busStop -> 
    spot.distance(busStop.getGPSCoordinate()));
Function distanceToSpot=memoize(总线停止->
点距离(bustop.getGPSCoordinate());
然后,声明比较器
,如下所示:

Comparator<Stop> byDistanceToSpot = Comparator.comparing(distanceToSpot);
Comparator byDistanceToSpot=比较器。比较(distanceToSpot);
最后,使用此比较器对公交站点集合进行排序:

Stop[] viableBusStops = stops.values().stream()
    .filter(busStop -> distanceToSpot.apply(busStop) <= threshold)
    .sorted(byDistanceToSpot) // only sort bus stops within threshold
    .toArray(Stop[]::new);
Stop[]viableBusStops=stops.values().stream()

.filter(总线停止->distanceToSpot.apply(总线停止)使用内置的Collections.sort方法使用属性
stop
distance
创建一个
StopDistance
类型,并将其而不是
stop
实例存储在临时集合中。相应地进行排序。实际上
TreeMap
使用距离作为
键是个坏主意,因为您将遇到如果多个站点到
点的距离相同,则会出现问题
我喜欢你的方法,但我认为终端操作是错误的。也许你应该在
之前添加
.map(map.Entry::getKey)
。toArray(Stop[]::new)