I was asked this recently in an interview. Application that is reading ticker and trade volume from a live feed, E.g. AAPL 1000, TWTR 500, MSFT 500, AAPL 500 ... So, AAPL
Assuming ticker symbol and trade volume are stored together in an instance of some class TickerAndTradeVolume, you could have references to objects contained in multiple data structures.
So a hash map may have ticker symbol as key and TickerAndTradeVolume as value. Then references to TickerAndTradeVolume instances can also be stored in a priority queue. Instances are re-inserted into the PQ on every volume update.
The top n by volume are always available in log(n) amortized time complexity to maintain priorities by trade volume, which is asymptotically faster than sorting via Treemap time and again.
Something like this
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;
}