Since, the hardware is becoming very cheap and has very huge memory available these days.Why cannot we use generically a common DataStructure like HashMap for all the scenarios ? If not, is there a short guideline somewhere to know which DataStructure to use in which scenario?.
Since, the hardware is becoming very cheap and has very huge memory available these
Share
(Edit: This answer assumes that you’re asking within the context of storing
key -> valuemappings. If your data doesn’t naturally represent mappings, for example a list of Strings, then any kind ofMapis a poor way to represent it, both in terms of performance and in terms of confusing anyone else who looks at your code.)Generally speaking, you can. If you’re using a map with immutable keys that have decent
hashCode()implementations (e.g.String, any of the auto-boxed primitives), then a HashMap will be perfectly acceptable in general.However, the different data structures exist for a reason – they all offer difference performance (and occasionally correctness) semantics, so in certain situations you may wish to pick others.
For example, if you want your map entries to be visited in a particular order during iteration (based on the keys), you can use a
TreeMap. If you want the iteration order to be based on the order they were inserted, use aLinkedHashMap. If you want good performance under simple concurrent access (with put-if-absent semantics), use aConcurrentHashMap. If your keys are enums, then anEnumMapis hands-down the most efficient implementation. If you want the keys to be stored as weak refs, use aWeakHashMap. If you want to perform lookups based on the exact object being used (making it safe for mutable keys), useIdentityHashMap.Not to mention that if you know (but are unable to change) that your keys have a poorly-implemented
hashCode()method, especially if it’s inconsistent with equals, thenHashMapmay be a poor choice anyway.And there are many other possible features you may wish your data structure to have that aren’t covered able, included (but not limited to):
get()is performed for a key that isn’t thereAnd so on. This is especially likely if your own domain objects have certain properties that a specific
Mapimplementation could take advantage of for faster/cleaner/enhanced performance (which, of course, a generic library implementation could never do).Addressing the “hardware is cheap” statement – this is true, but programmer time and user time is not. In some cases, the application’s critical loop may involve a lot of map lookups, such that speeding up these lookups will have a noticeable effect on performance. Of course, this usually won’t be the case, but if it is, choosing a better performing map for the specific situation (a simple example that comes to mind is using an
EnumMapwhere appropriate) will yield performance gains – which can be very important.Alternatively, some map implementations simply make the surrounding code easier to write, easier to understand, and less likely to harbour bugs. An example here might be a case of a lazy-initialising map (something like Google Collections’ ComputingMap). While you can write some code with lazy-init semantics around a standard
HashMap, by packing all of this logic inside the map implementation itself it becomes easier to test for correctness – and the client logic is much simpler.So cheap hardware/space doesn’t mean that HashMaps are optimal for everything. In fact, if anything it’s a counterargument – HashMaps are reasonably space-efficient compared to the more bespoke alternatives you might adopt. With lots of cheap space available, it’s entirely possible to trade off space against time, storing lots of information in order to speed up lookups.
Note that I’ve interpreted your question as “why might you sometimes use other classes of
Map?” rather than “which otherMapsshould you use and when?” If it’s the latter, feel free to rephrase or ask another question that focuses on this more specifically.