简体   繁体   中英

Which Map data structure in Java for getting highest element most efficiently?

TreeMap has O(log n) performance (best case), however, since I need the following operations efficiently:

  • get the highest element
  • get XY highest elements
  • insert

Other possibility would be to make a PriorityQueue with the following:

  • use " index " element as order for PriorityQueue
  • equals implementation to check only "index" element equality but this would be a hack since "equals" method would be error prone (if used outside of PriorityQueue ).

Any better structure for this?

More details below which you might skip since the first answer provided good answer for this specifics, however, I'm keeping it active for the theoretical discussion.

NOTE: I could use non standard data structures, in this project I'm already using UnrolledLinkedList since it most likely would be the most efficient structure for another use.

THIS IS USE CASE (in case you are interesting): I'm constructing AI for a computer game where

  OffensiveNessHistory myOffensiveNess = battle.pl[orderNumber].calculateOffensivenessHistory();

With possible implementations:

public class OffensiveNessHistory {
  PriorityQueue<OffensiveNessHistoryEntry> offensivenessEntries = new PriorityQueue<OffensiveNessHistoryEntry>();
..

or

public class OffensiveNessHistory {
  TreeMap<Integer, OffensiveNessHistoryEntry> offensivenessEntries = new TreeMap();
..

I want to check first player offensiveness and defensiveness history to calculate the predict if I should play the most offensive or the most defensive move.

First, you should think about the size of the structure (optimizing for just a few entries might not be worth it) and the frequency of the operations.

If reads are more frequent than writes (which I assume is the case), I'd use a structure that optimizes for reads on the cost of inserts, eg a sorted ArrayList where you insert at a position found using a binary search. This would be O(log n) for the search + the cost of moving other entries to the right but would mean good cache coherence and O(1) lookups.

A standard PriorityQueue internally also uses an array, but would require you to use an iterator to get element n (eg if you'd at point need the median or the lowest entry).

There might be strutures that optimize write even more while keeping O(1) reads but unless those writes are very frequent you might not even notice any performance gains.

Finally and foremost, you should try not to optimize on guesses but profile first. There might be other parts of your code that might eat up performance and which might render optimization of the datastructures rather useless.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM