Differences between HashMap and TreeMap in Java

Source: Internet
Author: User
Tags java keywords

First, we will introduce what Map is. In the array, We index its content through the array subscript, while in the Map, we index the object through the object. The object to be indexed is called the key, the corresponding object is value. This is what we usually call a key-value pair.

HashMap uses hashcode to quickly search its content, while all elements in TreeMap maintain a fixed order, if you need to get an ordered result, you should use TreeMap (the arrangement order of elements in HashMap is not fixed ).
HashMap non-thread security TreeMap non-thread security

Thread Security
In Java, thread security is generally reflected in two aspects:
1. Multiple Threads access the same java instance (read and modify) without interfering with each other. It is mainly reflected in the key word synchronized. Such as ArrayList and Vector, HashMap, and Hashtable
(The latter has the synchronized keyword before each method ). If you remove an element from another thread while interator is a List object, the problem occurs.

2. Each thread has its own field instead of sharing it among multiple threads. It is mainly reflected in the java. lang. ThreadLocal class, and is not supported by Java keywords, such as static and transient.
1. AbstractMap abstract class and SortedMap Interface
AbstractMap abstract class: (HashMap inherits AbstractMap) overwrites the equals () and hashCode () methods to ensure that the two equal mappings return the same hash code. If the two mappings are of the same size, contain the same key, and each key has the same value in the two mappings, the two mappings are equal. The mapped hash code is the sum of the mapped element hash codes. Each element is an implementation of the Map. Entry interface. Therefore, two equal mappings report the same hash code regardless of the internal order of the ing.
SortedMap interface: (TreeMap inherits from SortedMap) it is used to maintain the orderly order of keys. The SortedMap interface is the image view (subset), including two endpoints that provide access methods. Except for sorting keys acting on mappings, SortedMap processing is the same as SortedSet processing. The elements added to the SortedMap implementation class must implement the Comparable interface. Otherwise, you must provide a Comparator interface for its constructor. The TreeMap class is its only implementation.

2. Two conventional Map implementations
HashMap: implemented based on hash tables. The key classes required to be added using HashMap clearly define hashCode () and equals () [hashCode () and equals ()]. To optimize the use of HashMap space, you can optimize the initial capacity and load factor.
(1) HashMap (): Construct an empty hash image.
(2) HashMap (Map m): Build a hash image and add all Mappings of the image m.
(3) HashMap (int initialCapacity): creates an empty hash image with a specific capacity.
(4) HashMap (int initialCapacity, float loadFactor): Build an empty hash image with a specific capacity and loading Factor
TreeMap: implemented based on the red and black trees. TreeMap has no optimization option because the tree is always in the balance state.
(1) TreeMap (): Construct an empty image tree
(2) TreeMap (Map m): build an image tree and add all elements in image m.
(3) TreeMap (Comparator c): build an image tree and use a specific Comparator to sort keywords.
(4) TreeMap (SortedMap s): build an image tree, add all mappings in the image tree s, and sort by the same comparator as the ordered image s.

3. Two common Map performances
HashMap: applies to inserting, deleting, and locating elements in a Map.
Treemap: Applicable to traversing keys in natural or custom order ).

4. Summary
HashMap is usually a little faster than TreeMap (because of the data structure of the tree and hash table). We recommend that you use HashMap to use TreeMap only when you need to sort the Map.

Copy codeThe Code is as follows: import java. util. HashMap;
Import java. util. Hashtable;
Import java. util. Iterator;
Import java. util. Map;
Import java. util. TreeMap;
Public class HashMaps {
Public static void main (String [] args ){
Map <String, String> map = new HashMap <String, String> ();
Map. put ("a", "aaa ");
Map. put ("B", "bbb ");
Map. put ("c", "ccc ");
Map. put ("d", "ddd ");
Iterator <String> iterator = map. keySet (). iterator ();
While (iterator. hasNext ()){
Object key = iterator. next ();
System. out. println ("map. get (key) is:" + map. get (key ));
}
// Define HashTable for testing
Hashtable <String, String> tab = new Hashtable <String, String> ();
Tab. put ("a", "aaa ");
Tab. put ("B", "bbb ");
Tab. put ("c", "ccc ");
Tab. put ("d", "ddd ");
Iterator <String> iterator_1 = tab. keySet (). iterator ();
While (iterator_1.hasNext ()){
Object key = iterator_1.next ();
System. out. println ("tab. get (key) is:" + tab. get (key ));
}
TreeMap <String, String> tmp = new TreeMap <String, String> ();
Tmp. put ("a", "aaa ");
Tmp. put ("B", "bbb ");
Tmp. put ("c", "ccc ");
Tmp. put ("d", "cdc ");
Iterator <String> iterator_2 = tmp. keySet (). iterator ();
While (iterator_2.hasNext ()){
Object key = iterator_2.next ();
System. out. println ("tmp. get (key) is:" + tmp. get (key ));
}
}
}

The running result is as follows:
Map. get (key) is: ddd
Map. get (key) is: bbb
Map. get (key) is: ccc
Map. get (key) is: aaa
Tab. get (key) is: bbb
Tab. get (key) is: aaa
Tab. get (key) is: ddd
Tab. get (key) is: ccc
Tmp. get (key) is: aaa
Tmp. get (key) is: bbb
Tmp. get (key) is: ccc
Tmp. get (key) is: cdc
HashMap results are not sorted, while TreeMap output results are sorted.
The following is the topic of this article. The following example shows how to use HashMap:Copy codeThe Code is as follows: import java. util .*;
Public class Exp1 {
Public static void main (String [] args ){
HashMap h1 = new HashMap ();
Random r1 = new Random ();
For (int I = 0; I <1000; I ++ ){
Integer t = new Integer (r1.nextInt (20 ));
If (h1.containsKey (t ))
(Ctime) h1.get (t). count ++;
Else
H1.put (t, new Ctime ());
}
System. out. println (h1 );
}
}
Class Ctime {
Int count = 1;
Public String toString (){
Return Integer. toString (count );
}
}

In HashMap, get () is used to obtain the value, put () is used to insert the value, and ContainsKey () is used to check whether the object already exists. It can be seen that, compared with the ArrayList operation, HashMap not only indexes its content through the key, but also has little difference in other aspects.
As mentioned above, HashMap is based on HashCode. There is a HashCode () method in the super-class Object of all objects, but it is the same as the equals method and cannot apply to all situations, in this way, we need to rewrite our own HashCode () method. The following is an example:Copy codeThe Code is as follows: import java. util .*;
Public class Exp2 {
Public static void main (String [] args ){
HashMap h2 = new HashMap ();
For (int I = 0; I <10; I ++)
H2.put (new Element (I), new Figureout ());
System. out. println ("h2 :");
System. out. println ("Get the result for Element :");
Element test = new Element (5 );
If (h2.containsKey (test ))
System. out. println (Figureout) h2.get (test ));
Else
System. out. println ("Not found ");
}
}
Class Element {
Int number;
Public Element (int n ){
Number = n;
}
}
Class Figureout {
Random r = new Random ();
Boolean possible = r. nextDouble ()> 0.5;
Public String toString (){
If (possible)
Return "OK! ";
Else
Return "Impossible! ";
}
}

In this example, the Element is used to index the object Figureout, that is, the Element is the key, and the Figureout is the value. A floating point number is randomly generated in Figureout. If it is larger than 0.5, print "OK! ", Otherwise print" Impossible! ". Then, view the Figureout result corresponding to Element (3.

The result shows that no matter how many times you run it, the result is "Not found ". That is to say, the index Element (3) is not in HashMap. How is this possible?
The reason is that the HashCode method of the Element inherits from the Object, while the HashCode returned by the HashCode method in the Object corresponds to the current address, that is, for different objects, even if their content is identical, the values returned with HashCode () are also different. This actually violates our intention. Because when we use HashMap, we want to use the same content of the object index to get the same target object, which requires HashCode () to return the same value at this time. In the preceding example, we expect that the new Element (I) (I = 5) and Elementtest = newElement (5) are the same, but actually they are two different objects, although they share the same content, they have different addresses in the memory. So naturally, the above program won't get the result we imagined. The following changes to the Element class:Copy codeThe Code is as follows: class Element {
Int number;
Public Element (int n ){
Number = n;
}
Public int hashCode (){
Return number;
}
Public boolean equals (Object o ){
Return (o instanceof Element) & (number = (Element) o). number );
}
}

Here, Element overwrites the hashCode () and equals () methods in the Object. Overwrite hashCode () so that it returns the value of number as hashcode, so that their hashcode is the same for objects with the same content. Overwrite equals () is used to make the result meaningful when HashMap judges whether two keys are equal (related to rewriting equals () for more information, see my another article "re-compile methods in the Object class". The modified program running result is as follows:
H2:
Get the result for Element:
Impossible!
Remember: If you want to use HashMap effectively, you must overwrite it in its HashCode ().
There are two principles for rewriting HashCode:
[List = 1]
You don't have to generate a unique hashcode for each different object, as long as your HashCode method enables get () to get the content put in put. That is, "Not one principle ".

The hashcode generation algorithm tries its best to make the hashcode values more scattered, rather than a lot of hashcode is concentrated in a range, which is conducive to improving the performance of HashMap. That is, the "Decentralization principle ". For the specific reasons for the second principle, if you are interested, refer to Bruce Eckel's Thinking in Java, where I will introduce the internal implementation principles of HashMap. I will not go into details here.
With these two principles, you can use HashMap to write your own program. I don't know if you have noticed this. java. lang. although clone (), equals (), and hashCode () methods are typical, they are not applicable in many cases, they are simply obtained by the object address. This requires us to rewrite them in our own programs. In fact, the java class library has also rewritten thousands of such methods. With object-oriented polymorphism-overwrite, Java designers elegantly construct the Java structure and reflect the characteristics of Java as a pure OOP language.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.