阅读收藏和检索前5名

时间:2015-03-03 04:26:43

标签: collections

我最近在接受采访时被问到这个问题。从实时订阅源读取股票代码和交易量的应用程序, 例如。 AAPL 1000,TWTR 500,MSFT 500,AAPL 500 ...... 所以,AAPL总量= 1500,依此类推。 我必须把它们读成一个集合并按体积返回前5个。

我建议在存储时使用哈希映射,然后排序或使用Treemap。 还有其他更有效的方式吗?

1 个答案:

答案 0 :(得分:0)

假设股票代码和交易量一起存储在某个类TickerAndTradeVolume的实例中,您可以引用多个数据结构中包含的对象。

因此,哈希映射可以将股票代码作为关键字,将TickerAndTradeVolume作为值。然后,对TickerAndTradeVolume实例的引用也可以存储在优先级队列中。每次卷更新时都会将实例重新插入PQ。

按卷分列的前n个总是以log(n)摊销的时间复杂度提供,以按交易量维持优先级,这比通过Treemap一次又一次地进行排序的速度渐渐快。

像这样的东西

    Map<String, TickerAndTradeVolume> feed;
    PriorityQueue<TickerAndTradeVolume> pq;

    class TickerAndTradeVolume implements Comparable<TickerAndTradeVolume> {
        private String ticker;
        private double volume;

        TickerAndTradeVolume(String ticker, double volume) {
            this.ticker = ticker;
            this.volume = volume;
        }

        void increaseVolumeBy(double volume) {
            this.volume += volume;
        }

        @Override
        public int compareTo(TickerAndTradeVolume that) {
            return (int) (that.volume - this.volume);
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if(obj instanceof String) {
                TickerAndTradeVolume that = (TickerAndTradeVolume) obj;
                return this.ticker.equals(that.ticker);
            }
            return false;
        }
    }

    void addOrUpdateStockVolume(TickerAndTradeVolume tt) {
        if(!feed.containsKey(tt.ticker)) {
            feed.put(tt.ticker, tt);
            pq.add(tt);
        }
        else {
            feed.get(tt.ticker).increaseVolumeBy(tt.volume);
            // take out and put back in to trigger heap operations
            pq.remove(feed.get(tt.ticker));
            pq.add(feed.get(tt.ticker));
        }
    }

    List<TickerAndTradeVolume> getTopMaxFive() {
        List<TickerAndTradeVolume> topFive = new ArrayList<TickerAndTradeVolume>(5);
        int pqSize = pq.size();
        for(int i = 0; i < 5 && i < pqSize; i++) {
            // poll() takes from the top of the heap
            topFive.add(pq.poll());
        }
        for(TickerAndTradeVolume tt : topFive) {
            // put back what we took out
            pq.add(tt);
        }
        return topFive;
    }