This article mainly analyzes the Java set framework in the Map part, HashMap, the source analysis based on JDK1.8, analysis tools, AndroidStudio, the article analysis of shortcomings, please forgive me!

Introduction of a HashMap

Hash table based on a Map interface implementation, the storage object is a key-value pair object (Entry<K,V>); It is important to note that HashMaps are not thread-safe. If you want a thread-safe HashMap, you can obtain a thread-safe HashMap through synchronizedMap, the static method of the Collections class.

Map map = Collections.synchronizedMap(new HashMap());
Copy the code

The data structure

The most basic data structures in Java are arrays and linked lists. Arrays are characterized by contiguous space (fixed size), fast addressing, but insert and delete elements need to move, so the query is fast, add and delete slow. On the contrary, linked lists can dynamically increase or decrease space to accommodate the addition and deletion of elements, but the search can only be along the node search, so the increase and deletion is fast, the search is slow. Is there a structure that combines the best of arrays and linked lists? Of course, there is a hash table (although it is a comprehensive advantage, but in fact, certainly not as fast as array lookup, insert and delete not as fast as linked list, a compromise way), all data structures can use these two basic structures to construct, HashMap is no exception. A HashMap is actually a “linked list hash” data structure, which is a combination of arrays and lists.

The underlying implementation of HashMap is mainly based on arrays and linked lists, and its query speed is relatively fast mainly because it calculates hash codes to determine the location of storage. In a HashMap, the key’s hashCode is used to calculate the hash value. If the hashCode is the same, the calculated hash value is the same. If there are too many pairs of objects, it is possible that different objects will have the same hash value, which is called hash conflict. Those of you who have studied data structures know that there are many ways to resolve hash conflicts. At the bottom of a HashMap, hash conflicts are resolved through linked lists. Each element of the array is the head node of a single linked list. Linked lists are used to resolve conflicts. If different keys map to the same location in the array, they are put into the single linked list.

The internal interface

Internal interface The EntryEntry interface is an internal interface defined by a Map

 interface Entry<K, V> {
	K getKey();
	V getValue();
	V setValue(V value);
	boolean equals(Object o);
	int hashCode();
	public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K, V>> comparingByKey() {
		return (Comparator<Map.Entry<K, V>> & Serializable) (c1, c2) -> c1.getKey().compareTo(c2.getKey());
	}
	public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K, V>> comparingByValue() {
		return (Comparator<Map.Entry<K, V>> & Serializable) (c1, c2) -> c1.getValue().compareTo(c2.getValue());
	}
	public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp) {
		Objects.requireNonNull(cmp);
		return (Comparator<Map.Entry<K, V>> & Serializable) (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
	}
	public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) {
		Objects.requireNonNull(cmp);
		return(Comparator<Map.Entry<K, V>> & Serializable) (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue()); }}Copy the code

For a HashMap, it implements a static inner class, HashMapEntry<K,V>, whose important properties are key, value, next, HashMapEntry is the basic bean for implementing the HashMap key-value pair. We have mentioned above that the basis of HashMap is a linear array. This array is HashMapEntry[]. The contents of the Map are stored in HashMapEntry[].

transient HashMapEntry<K,V>[] table = (HashMapEntry<K,V>[]) EMPTY_TABLE;
Copy the code

We can briefly examine the static inner class hashMapEntry.java

// hashmapEntry. Java static inner class, Static class HashMapEntry<K, V> implements map. Entry<K, V> {// key,value value final K key; V value; // Each array contains a list HashMapEntry<K, V> next; inthash; /** * Constructor * input parameters include"Hash (h)"."Key (k)"."Value (v)"."Next node (n)" */
	HashMapEntry(int h, K k, V v, HashMapEntry<K, V> n) {
		value = v;
		next = n;
		key = k;
		hash = h;
	}
	public final K getKey() {
		return key;
	}
	public final V getValue() {
		return value;
	}
	public final V setValue(V newValue) {
		V oldValue = value;
		value = newValue;
		returnoldValue; } /** ** Check whether two entries are equal * If the key and value of two entries are equal, this field is returnedtrue. * Otherwise, returnfalse
	 */
	public final boolean equals(Object o) {
		if(! (o instanceof Map.Entry))return false;
		Map.Entry e = (Map.Entry) o;
		Object k1 = getKey();
		Object k2 = e.getKey();
		if(k1 == k2 || (k1 ! = null && k1.equals(k2))) { Object v1 = getValue(); Object v2 = e.getValue();if(v1 == v2 || (v1 ! = null && v1.equals(v2)))return true;
		}
		return false;
	}
	public final int hashCode() {
		return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue());
	}
	public final String toString() {
		return getKey() + "="+ getValue(); } /** ** recordAccess() */ void recordAccess(HashMap<K, V> m) {} /** ** when removing elements from HashMap, RecordRemoval () is called. */ void recordRemoval(HashMap<K, V> m) { } }Copy the code

A HashMap is actually a HashMapEntry array, which contains keys and values. Next is also a HashMapEntry object, which is used to handle hash conflicts and form a linked list. Now that we have analyzed the basic structure, let’s get down to business and start analyzing the source implementation of HashMap.

Source code analysis

Class declaration

public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
Copy the code

Let’s start by looking at some of the attributes declared inside the HashMap,

The default initial capacity must be a power of 2. static final int DEFAULT_INITIAL_CAPACITY = 4; Static final int MAXIMUM_CAPACITY = 1 << 30; // Load the factor static finalfloatDEFAULT_LOAD_FACTOR = 0.75 f; // static final HashMapEntry<? ,? >[] EMPTY_TABLE = {}; Transient HashMapEntry<K,V>[] TABLE = (HashMapEntry<K,V>[]) EMPTY_TABLE; // Number of key-value mappings in the current Map TRANSIENT int size; // When the actual size exceeds the threshold, the capacity will be expanded. Threshold = Load factor * capacity int threshold; // Load factor finalfloatloadFactor = DEFAULT_LOAD_FACTOR; // Transient int modCount;Copy the code

LoadFactor loadFactor loadFactor

The loadFactor indicates the extent to which elements in the Hsah table are filled.

If: The larger the loading factor is, the more elements are filled, the advantage is that the space utilization is high, but: the chance of conflict is increased. The list length will get longer and longer, and the search efficiency will decrease. Conversely, the smaller the loading factor, the fewer elements are filled, which has the advantage of: less chance of conflict, but: more wasted space. The data in the table will be too sparse (a lot of space is already expanding before it is used) and the greater the chance of conflicts, the higher the cost of lookups. Therefore, a balance and compromise must be found between “opportunities for conflict” and “space utilization”. This balance and tradeoff is essentially a balance and tradeoff of the famous time-space contradiction in data structures.

If the machine has enough memory and you want to speed up the query, you can set the load factor to be smaller. On the contrary, if the machine is short of memory and there is no requirement for query speed, you can set the load factor to be larger. However, we don’t need to set it. The default value is 0.75. Some of the above basic attributes are declared in the HashMap, so you can wait until later if you don’t know what they mean. Let’s move on to the following code.

The constructor

Next, let’s examine the HashMap constructors

/** ** Set the initial capacity size and load factor ** ** @param initialCapacity The initial capacity ** @param loadFactor the load factor ** @throws IllegalArgumentExceptionif the initial capacity is negative     
 * *         or the load factor is nonpositive     
 * */    
public HashMap(int initialCapacity, floatLoadFactor) {// The initial capacity is between [DEFAULT_INITIAL_CAPACITY,MAXIMUM_CAPACITY]if (initialCapacity < 0)           
		throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity);
	if (initialCapacity > MAXIMUM_CAPACITY) {
		initialCapacity = MAXIMUM_CAPACITY;       
		} 
	else if (initialCapacity < DEFAULT_INITIAL_CAPACITY) { 
		initialCapacity = DEFAULT_INITIAL_CAPACITY;       
		}       
	if (loadFactor <= 0 || Float.isNaN(loadFactor)) 
		throw new IllegalArgumentException("Illegal load factor: "+ loadFactor); threshold = initialCapacity; init(); } /** ** * Set the initial capacity with the default loading factor of 0.75 ** @param initialCapacity the initialCapacity. ** @throws IllegalArgumentExceptionifthe initial capacity is negative. * */ public HashMap(int initialCapacity) { this(initialCapacity, DEFAULT_LOAD_FACTOR);  } /** ** uses the default capacity size and load factor ** / publicHashMap() { this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR); } /** ** Generates a new HashMap based on the specified map, using the default load factor, * The initial capacity is math.max ((int) (m.ize ()/DEFAULT_LOAD_FACTOR) + 1,DEFAULT_INITIAL_CAPACITY) * * * * @param m the map whose mappings are to be placedin this map     
 *     * @throws  NullPointerException ifthe specified map is null * */ public HashMap(Map<? extends K, ? extends V> m) { this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1, DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR); // Initializes the HashMapEntry array inflateTable(threshold); putAllForCreate(m); }}Copy the code

We can construct a HashMap by setting the initial capacity and load factor, or directly from a map. The initial capacity is set to 4, which must be a power of 2. And it’s in the range between 4 and 2 to the 30th. The constructors are relatively simple and there is nothing to analyze, so let’s focus on the add and get methods of a HashMap, namely the PUT and get methods.

Storing data PUT

Public V put(K key, V value) {// If the HashMapEntry array is empty, reinitialize itif(table == EMPTY_TABLE) { inflateTable(threshold); } // putForNullKey is called for key-value pairs whose key is nullif (key == null)            
		returnputForNullKey(value); / / generatedhashValue of the inthash= sun.misc.Hashing.singleWordWangJenkinsHash(key); / / generatedhashInt I = indexFor(hash, table.length); // Loop through the Entry array. If the key-value pair corresponding to "this key" already exists, replace the old value with the new value. Then exit, returning the old value!for(HashMapEntry<K,V> e = table[i]; e ! = null; e = e.next) { Object k; // If the same key is found, override the old valueif (e.hash == hash&& ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; // Call HashMapEntry to add the Entry e.recordAccess(this);returnoldValue; ModCount++; // add key-value to table[I], i.e. insert data <k,v> addEntry(hash, key, value, i);        
	returnnull; }}Copy the code

The hash value of the key is obtained, and the hash value is used to obtain the position of the key in the array. The hash value is used to determine whether the key exists in the table[I]. If the key is found, the key is replaced. If the key is not found in the list, insert a value at the head of the list. In the PUT method, let’s examine some of these methods in detail. There is an operation at the beginning to determine whether the array is null

// If the HashMapEntry array is empty, reinitialize itif(table == EMPTY_TABLE) { inflateTable(threshold); } /** ** * initializes the array ** / private void inflateTable(int toSize) {// Find the smallest value greater than toSize (2) int capacity = roundUpToPowerOf2(toSize);float thresholdFloat = capacity * loadFactor;       
	if(thresholdFloat > MAXIMUM_CAPACITY + 1) { thresholdFloat = MAXIMUM_CAPACITY + 1; } // Initialize the array threshold = (int) thresholdFloat; table = new HashMapEntry[capacity]; }}Copy the code

If the key is null, putForNullKey(V value) is putForNullKey

** / private V putForNullKey(V value) {// Loop over the list of the first array in the array, overwrite the list if there is nullfor(HashMapEntry<K,V> e = table[0]; e ! = null; e = e.next) {if (e.key == null) {                
			V oldValue = e.value; 
			e.value = value;                
			e.recordAccess(this);                
			returnoldValue; ModCount++; AddEntry (0, NULL, value, 0) is inserted at the beginning of the list.returnnull; }}Copy the code

If the key is null, the hash value is 0, and the object is stored at the 0 index in the array. Table [0], and then we look at the addEntry method,

/ / byhashVoid addEntry(int) void addEntry(inthash, K key, V value, int bucketIndex) {
	//        
	if((size >= threshold) && (null ! = table[bucketIndex])) {resize(2 * table.length); // If key is null, thenhashThe value is 0, which is the first position in the array, the table[0] positionhash= (null ! = key) ? sun.misc.Hashing.singleWordWangJenkinsHash(key) : 0; / / according tohashBucketIndex = indexFor(bucketIndex = indexFor(hash, table.length); } // Data insert or update operation createEntry(hash, key, value, bucketIndex);    
}
Copy the code

We hash out the values in the table below, then move on to the createEntry method

// Insert an array at the head of a list. This is the process of inserting a node at the head of a list. Select e from table[I], modify table[I] as new object, and make next point of new object refer to e. void createEntry(inthash, K key, V value, int bucketIndex) {HashMapEntry<K,V> e = table[bucketIndex]; // Then change the value of table[I] to the new object, and set the next value of the new object to the original value of table[I] e. This is equivalent to inserting data into the head of the list. table[bucketIndex] = new HashMapEntry<>(hash, key, value, e); size++; }}Copy the code

After analyzing the case where the key is null, let’s analyze the case where the key is not null. Int I = indexFor(hash, table.length); int I = indexFor(hash, table.length);

/ / indexFor returnshashValue and the length of the table array minus 1. Why length-1? In this way, the maximum value of the result can be guaranteed to be length-1, and there will be no out-of-bounds problem of the array. static int indexFor(int h, int length) {return h & (length-1);   
}
Copy the code

Once we find the position in the array table, we start iterating through the list in the current position, overwriting the key if it is present, and inserting a piece of data into the list header if it is not. This is a complete add-data operation, and here we summarize the main idea. First, we determine whether the key we want to add to the data is null. If it is null, we insert or update the data at the first position of the array, that is, table[0]. If the first position of the linked list does not have a null key, then we overwrite the update. Insert a key into the table if it does not exist. Insert a key into the table if it does not exist. Insert a key into the table if it does not exist. We repeat what we did in the list (overwrite the update if we found it, insert a piece of data at the head of the list if we didn’t find it), which is the PUT operation for the HashMap.

Generally, it is natural for us to think of modulo length with hash value (i.e. division hash method), which is also implemented in Hashtable. This method can basically ensure the uniform hash of elements in the hash table, but the efficiency is very low due to division operation. In HashMap, h&(Length-1) is used to replace modulus, which also realizes uniform hash, but with much higher efficiency. This is also an improvement of HashMap over Hashtable. Now, let’s see why the hash table has to be an integer power of two. First of all, if length is an integer power of 2, h&(length-1) is equivalent to modulo length, so as to ensure the uniformity of the hash, but also improve the efficiency; Secondly, if length is 2 to the power of the integer, it is even, so that length-1 is odd, and the last bit of the odd is 1, which guarantees that h&(Length-1) may have the last bit of 0 or 1 (depending on the value of h), that is, the result of and may be even or odd. If length is odd, it is obvious that length-1 is even, and the last digit of length-1 is 0, then h&(Length-1) must have the last digit of 0, that is, it can only be even. Any hash value is then only hashed to the even index of the array, wasting nearly half of the space. Therefore, length is an integer power of 2 to minimize the probability that different hash values will collide, so that elements will be evenly hashed across the hash table. Now that we’ve looked at the PUT method, let’s look at the putAll method,

/**     
 * * @param m mappings to be stored in this map     
 * * @throws NullPointerException if the specified map is null     
 * */    
public void putAll(Map<? extends K, ? extends V> m) { 
	int numKeysToBeAdded = m.size();        
	if (numKeysToBeAdded == 0)            
		return;        
	if(table == EMPTY_TABLE) { inflateTable((int) Math.max(numKeysToBeAdded * loadFactor, threshold)); } / * * /if (numKeysToBeAdded > threshold) {  
		int targetCapacity = (int)(numKeysToBeAdded / loadFactor + 1);          
		if (targetCapacity > MAXIMUM_CAPACITY)                
			targetCapacity = MAXIMUM_CAPACITY;            
		int newCapacity = table.length;           
		while (newCapacity < targetCapacity)               
			newCapacity <<= 1;           
		if(newCapacity > table.length) resize(newCapacity); } // iterate through the contents of m, and then call the PUT method to add the element to the table arrayfor(Map.Entry<? extends K, ? extends V> e : m.entrySet()) put(e.getKey(), e.getValue()); }}Copy the code

Traversal involves the entrySet method, which is defined in the Map interface and implemented in HashMap. We have a method in the HashMap constructor called putAllForCreate, so let’s look at that.

private void putAllForCreate(Map<? extends K, ? extends V> m) {        
    for (Map.Entry<? extends K, ? extends V> e : m.entrySet())                            
    	putForCreate(e.getKey(), e.getValue());    
}
Copy the code

The name of this method gives you a general idea of what it means. When a HashMap is initialized, the entire map is assigned to its initial value. So the code, let’s go through the Map, and then add it, and let’s go into the putForCreate method and see the source code

Private void putForCreate(K key, V value) {// Obtain the keyhashValue of the inthash= null == key ? 0 : sun.misc.Hashing.singleWordWangJenkinsHash(key); / / according tohashInt I = indexFor(hash, table.length); // Iterate over the list with subscript I, overwriting the update if it exists, which is the position in the table calculated abovefor(HashMapEntry<K,V> e = table[i]; e ! = null; e = e.next) { Object k;if (e.hash == hash&& ((k = e.key) == key || (key ! = null && key.equals(k)))) { e.value = value;return; }} // The position in the current array does not exist in the list.hash, key, value, i); }}Copy the code

This method computes the hash value of the element to be added and the index I in the table array. We then iterate through the linked list of table[I], and replace the value if there is an element whose key is equal to the key passed in, ending the method. If no element with the same key exists, createEntry is called to create and add the element. Continue into the createEntry method to view the source code

void createEntry(int hash, K key, V value, int bucketIndex) {
	HashMapEntry<K,V> e = table[bucketIndex];        
	table[bucketIndex] = new HashMapEntry<>(hash, key, value, e);        
	size++;   
}
Copy the code

The putAllForCreate method is similar to the PUT method by inserting a single piece of data into the head of the list. So far all put operations have been explained. Next to put, another common operation is get. Let’s look at the get method.

The get method

The get method is relatively simple compared to the PUT method, so let’s look at the implementation.

 
public V get(Object key) { 
	if (key == null)            
		return getForNullKey();       
	Entry<K,V> entry = getEntry(key);        
	return null == entry ? null : entry.getValue();   
}
Copy the code

First check whether the key is null. If it is, get the value from getForNullKey(). If not, get the value from getEntry. Let’s first look at the null case.

private V getForNullKey() {
	if (size == 0) {
		return null;        
	}        
	for(HashMapEntry<K,V> e = table[0]; e ! = null; e = e.next) {if (e.key == null)                
			return e.value;        
		}        
	return null;    
}
Copy the code

If the size of the current table is 0, then null will be returned. If the size of the current table is not empty, then the list in the array table[0] will be looped through, looking for the null list node of key, if found, then return value, otherwise return NULL. Very simple. We then analyze the case where the key is not null, which we do in the getEntry method.

final Entry<K,V> getEntry(Object key) {
	if (size == 0) {
		return null;        
	}        
	int hash = (key == null) ? 0 : sun.misc.Hashing.singleWordWangJenkinsHash(key);        
	for (HashMapEntry<K,V> e = table[indexFor(hash, table.length)]; e ! = null; e = e.next) { Object k;if (e.hash == hash&& ((k = e.key) == key || (key ! = null && key.equals(k))))return e;        
		}        
	return null;    
}
Copy the code

We have already analyzed the put method, so the code here is basically similar. It is very simple: first get the hash value, then get the index table[I] in the table based on the hash value, then loop through the linked list in table[I] based on the position in the array. Checks if the entry exists and returns value if it does, or NULL if it does not. Those are the two most important methods in HashMap, put and GET, and now that we’ve analyzed them all, let’s look at the rest.

The remove method

After analyzing the PUT and get methods, we will analyze the remove methods.

public V remove(Object key) {
	Entry<K,V> e = removeEntryForKey(key);        
	return (e == null ? null : e.getValue());    
}
Copy the code

In the remove method, we call a removeEntryForKey method, and let’s see,

Final Entry<K,V> removeEntryForKey(Object key) {// If the array is empty, null is returnedif (size == 0) { 
		returnnull; } // Get the key to removehashValue of the inthash= (key == null) ? 0 : sun.misc.Hashing.singleWordWangJenkinsHash(key); Int I = indexFor(int I = indexFor(hash, table.length); // Save the first list node in the current array HashMapEntry<K,V> prev = table[I]; HashMapEntry<K,V> e = prev;while(e ! = null) { HashMapEntry<K,V> next = e.next; Object k;if (e.hash == hash&& ((k = e.key) == key || (key ! = null && key.equals(k)))) { modCount++; size--;if (prev == e)                   
				table[i] = next;                
			else                    
				prev.next = next;                
			e.recordRemoval(this);                
			returne; } // single list delete operation prev = e; e = next; }returne; }}Copy the code

The above process is to find the corresponding index in the table array, and then similar to the general linked list delete operation, and one-way linked list delete node, very simple. In C, it is a pointer to modify. In this case, the next of the node to be deleted points to the next of the node to be deleted.

The rest of the way

This has covered most of the HashMap code, but there are some less important methods that we will explain at once rather than analyze at once.

To empty the map

/** ** Clear map ** / public voidclear() {
	modCount++;        
	Arrays.fill(table, null); 
	size = 0;   
	} 
Copy the code

** Checks whether the specified value ** exists

/** ** Check whether the specified value ** ** @param value value whose presence existsin this map is to be tested     
 * * @return <tt>true</tt> if this map maps one or more keys to the     
 * *         specified value     
 * */    
public boolean containsValue(Object value) {
	if (value == null)            
		return containsNullValue();        
	HashMapEntry[] tab = table;        
	for (int i = 0; i < tab.length ; i++)            
		for(HashMapEntry e = tab[i] ; e ! = null ; e = e.next)if (value.equals(e.value))                    
				return true;        
	return false;    
}  
Copy the code

Check if there is a node whose value is equal to null in the linked list below table[I]

/** ** select ** from table[I] where value = null ** / private BooleancontainsNullValue() {
	HashMapEntry[] tab = table;        
	for (int i = 0; i < tab.length ; i++)           
		for(HashMapEntry e = tab[i] ; e ! = null ; e = e.next)if (e.value == null)                    
				return true;        
	return false;    
}    

Copy the code

** Shallow copy of the HashMap **

/** ** For shallow copy of HashMap ** ** @return a shallow copy of this map     
 *  */    
public Object clone() {
	HashMap<K,V> result = null;        
	try {            
		result = (HashMap<K,V>)super.clone();        
		} 
	catch (CloneNotSupportedException e) { 
		// assert false;        
		}       
	if(result.table ! = EMPTY_TABLE) {result.inflatetable (math.min ((int) math.min (size * math.min (1 / loadFactor, 4.0f), // we have limits... HashMap.MAXIMUM_CAPACITY), table.length)); } result.entrySet = null; result.modCount = 0; result.size = 0; result.init(); result.putAllForCreate(this);returnresult; }}}Copy the code

This is the general source code for HashMap, which also covers the concept of entrySet, which is also covered by other collections frameworks, so it is not explained in this article. Stay tuned for future articles. If there is any mistake, please correct, thank you! Finally, let’s write a simple test to learn how to use HashMap in common.

package MapDemo;
import java.util.HashMap;
import java.util.Map;
public class HashMapTest {
	public static void main(String[] args) {
		
		Map<String, String> mHashMap=new HashMap<String,String>();
		mHashMap.put("A"."AAAAAAAA...");
		mHashMap.put("B"."BBBBBBBB...");
		mHashMap.put("C"."CCCCCCCC...");
		mHashMap.put("D"."DDDDDDDD...");
		mHashMap.put("E"."EEEEEEEE...");
		mHashMap.put("F"."FFFFFFFF...");
		mHashMap.put("G"."GGGGGGGG...");
		mHashMap.put("H"."HHHHHHHH...");
		mHashMap.put("I"."IIIIIIII..."); // Print HashMap system.out.println ("mHashMap: "+mHashMap); // Print HashMap size system.out.println ("mHashMap size is: "+mHashMap.size()); // Check whether A key exists in the HashMap. The result is TRUE system.out.println ("mHashMap is containsKey of A:"+ mHashMap.containsKey("A")); FALSE system.out.println (FALSE system.out.println ("mHashMap is containsValue of IIIIIIII:"+ mHashMap.containsValue("IIIIIIII")); // Print the key system.out.print ("the key of mHashMap is :");
		for (String string : mHashMap.keySet()) {
			System.out.print(""+string); } System.out.println(); // Print value system.out.print ("the value of mHashMap is :");
		for (String string : mHashMap.values()) {
			System.out.print(""+string); } System.out.println(); // Print the key-value set system.out.println ("The key - value set.");
		for (Map.Entry<String, String> entry : mHashMap.entrySet()) {
			System.out.println("key: "+entry.getKey()+" value: "+entry.getValue()); }}}Copy the code

The output

mHashMap: {A=AAAAAAAA... , B=BBBBBBBB... , C=CCCCCCCC... , D=DDDDDDDD... , E=EEEEEEEE... , F=FFFFFFFF... , G=GGGGGGGG... , H=HHHHHHHH... , I=IIIIIIII... } mHashMap size is: 9 mHashMap is containsKey of A:true
mHashMap is containsValue of IIIIIIII:falsethe key of mHashMap is : A B C D E F G H I the value of mHashMap is : AAAAAAAA... BBBBBBBB... CCCCCCCC... DDDDDDDD... EEEEEEEE... FFFFFFFF... GGGGGGGG... HHHHHHHH... IIIIIIII... Key-value set: key: A value: AAAAAAAA... key: B value: BBBBBBBB... key: C value: CCCCCCCC... key: D value: DDDDDDDD... key: E value: EEEEEEEE... key: F value: FFFFFFFF... key: G value: GGGGGGGG... key: H value: HHHHHHHH... key: I value: IIIIIIII...Copy the code

About the author

Focus on Android development for many years, like to write blog record summary learning experience, blog synchronous update in my public number, welcome everyone to pay attention to, exchange learning ~