开发者

In Java, Why cannot we use generically a common DataStructure like HashMap for all the scenarios?

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?.


(Edit: This answer assumes that you're asking within the context of storing key -> value mappings. If your data doesn't naturally represent mappings, for example a list of Strings, then any kind of Map is 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 a LinkedHashMap. If you want good performance under simple concurrent access (with put-if-absent semantics), use a ConcurrentHashMap. If your keys are enums, then an EnumMap is hands-down the most efficient implementation. If you want the keys to be stored as weak refs, use a WeakHashMap. If you want to perform lookups based on the exact object being used (making it safe for mutable keys), use IdentityHashMap.

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, then HashMap may 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):

  • Specific iteration order that isn't key-sorted or insertion-order
  • Size-boundedness (especially with customisable choice of which entry to kick out)
  • Soft/Phantom references for keys
  • Lazy initialisation when a get() is performed for a key that isn't there

And so on. This is especially likely if your own domain objects have certain properties that a specific Map implementation 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 EnumMap where 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 other Maps should you use and when?" If it's the latter, feel free to rephrase or ask another question that focuses on this more specifically.


To partially answer the first part of your question, note that there are important differences between the collection classes. Choosing one of them as the "default" would be tricky.

A HashMap is a Map, which is not always what you want - sometimes a List, or a Stack is most appropriate.

To answer the second part of your question, believe it or not but one of the best things I ever did was read the javadoc for the Collections package; each class has notes that I found really useful. For example, http://download.oracle.com/javase/6/docs/api/java/util/Collections.html gives an overview, and then choose any implementation like a Stack to find out more about it.

Good luck!


Because Hashmap is not ordered, because a stable hashcode is sometimes hard to define... Well for many reasons there are other structures. A good introduction is the Java Collections tutorial: http://download.oracle.com/javase/tutorial/collections/index.html


While a HashMap is useful in many situations, and yes, hardware is becoming very cheap, there are situations where information should be kept sequentially or at least in some type of order. Also, in the event of a data structure that a user may want to reorder (Say a student directory, it could be ordered by last name, first name, birthday, GPA, etc.) a HashMap may not be the easiest to work with. A HashMap could still be used in any situation that I can think of, but it could be easier, and definitely more computationally efficient to use a different structure in many situations.

Here's some reading: http://www.devx.com/tips/Tip/14639

http://java.sun.com/docs/books/performance/1st_edition/html/JPAlgorithms.fm.html (CTRL + F "8.4")

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜