订购从HashSet创建的数组的最有效方法

时间:2017-07-10 22:42:45

标签: java arrays hashset

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

我想按照相对于GPS坐标的距离来命令这个数组,这是最有效的方法吗?

Code: 

<html>
  <head>
    <meta charset="utf-8">
    <script type="text/javascript" src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.18/vue.min.js"></script>
  </head>

  <body>
    <div id="demo">
        <p>{{message}}</p>
    </div>

    <script>
        var demo = new Vue({
            el: '#demo',
            data: {
                message: 'Hello Vue.js!'
            }
        });
    </script>
</body>
</html>

编辑: 挑战是“距离”不是 Stop对象的属性。我想知道我是否可以对那些只计算一次距离的巴士站进行排序。

6 个答案:

答案 0 :(得分:1)

最有可能的方法是:Arrays.sort with Comparator

注意:您应该将计算出的距离缓存到Stop对象(或包装器)中的所需位置,以便在对象与Comparator进行比较时,在排序过程中不会多次执行此逻辑

您还可以考虑使用TreeMap,其中key是距离而valueStop - 然后提取值并将其转换为数组。

答案 1 :(得分:1)

构建一个Map<Stop, Double>,将停靠点与距离点的距离进行映射。然后根据距离对条目进行排序。

答案 2 :(得分:1)

您可以使用Java 8 Streams:

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;
}

答案 3 :(得分:0)

您是否考虑过使用比较器的Treeset?

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());

答案 4 :(得分:0)

试试这个。

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);
}

答案 5 :(得分:0)

如果您声明一个将公共汽车站作为参数并返回到该点的距离的函数,您可以创建一个比较器,根据它们到该点的距离对该公共汽车站进行排序,如函数所返回。

但是,为了完成其工作,比较器可能会多次访问一个给定元素,这意味着对于给定的公共汽车站,它到现场的距离最终可能会被计算多次。

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

您可以使用以下帮助程序方法实现memoization:

static <T, R> Function<T, R> memoize(Function<T, R> function) {
    Map<T, R> cache = new HashMap<>();
    return t -> cache.computeIfAbsent(t, function);
}

现在,为了解决您的问题,您可以创建一个memoized函数,它将一个公共汽车站作为参数并返回到现场的距离:

Function<Stop, Double> distanceToSpot = memoize(busStop -> 
    spot.distance(busStop.getGPSCoordinate()));

然后,按如下方式声明Comparator<Stop>

Comparator<Stop> byDistanceToSpot = Comparator.comparing(distanceToSpot);

最后,使用此比较器对您的公共汽车站集合进行排序:

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