前言——
HashMap的入门篇,非进阶篇,很适合入门,刷到这篇博文就好好学习鸭!!
一. 快速理解HashMap是什么
HashMap存储的是一种映射关系,关于key--value的映射。大家都学过函数吧, f(x) =y, 一个x代入函数表达式,有且只有一个y与之对应。可以说HashMap就是存储<key ,value>(比较一下 <x,f(x)>) 的映射关系。
二.HashMap的继承关系
public class HashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable { }
HashMap继承于AbstractMap类,实现了Map接口。
三.简单了解HashMap的原理
虽然这是HashMap的入门博客,不涉及进阶理解,但是为了能让大家更好的理解HashMap,还是得稍微提一下,如上面所说,HashMap存储的是一种映射关系------<key,value>,那么 是用什么类型的数据类型来存储 <key,value>呢,其实就是用一个节点,学过链表的同学应该很熟悉吧,就是定义了一种"Entry"类型的节点,这个节点可以存储key,也可以存储value,还能指向下一个节点。
这边提一下:在HashMap的源码中,主干是Entry[]数组,用于数据存储(其实原理挺简单,就是哈希算法+拉链法,再说白一点,就是使用了数组标记和链表而已,我以后会开一篇博文介绍滴~~)
transient Entry[] table;
四.HashMap中常用的函数
1.put(Object key ,Object value) 表示加入一种映射; (Object value)get(Object key)表示返回对应key的value
请看代码:
package Test;
import java.util.HashMap;
public class HashMapTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
HashMap<String,String> dictionaryMap = new HashMap();
dictionaryMap.put("apple","苹果");
dictionaryMap.put("banana","香蕉");
dictionaryMap.put("banana","香蕉1");
System.out.println(dictionaryMap.get("banana"));
}
}
/*
运行结果:
香蕉1
*/
这边要注意,后加入的映射中,如果前面已经有相同key的映射的话,后面加入的key值映射是会覆盖前面的,如上所示。原理跟
HashCode有关。
2.containsKey(Object key),查询是否存在对应key的映射,有的话返回true,没有的话返回false
package Test;
import java.util.HashMap;
public class HashMapTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
HashMap<String,String> dictionaryMap = new HashMap();
dictionaryMap.put("apple","苹果");
dictionaryMap.put("banana","香蕉");
System.out.println(dictionaryMap.containsKey("apple"));
System.out.println(dictionaryMap.containsKey("watermelon"));
}
}
/*
运行结果:
true
false
*/
3.containsValue(Object Value) ,查询是否存在对应Value的映射,有的话返回true,没有的话返回false
package Test;
import java.util.HashMap;
public class HashMapTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
HashMap<String,String> dictionaryMap = new HashMap();
dictionaryMap.put("apple","苹果");
dictionaryMap.put("banana","香蕉");
System.out.println(dictionaryMap.containsValue("香蕉"));
System.out.println(dictionaryMap.containsValue("西瓜"));
}
}
/*
运行结果:
true
false
*/
4.remove(Object key) ,删除键值为key的元素
package Test;
import java.util.HashMap;
public class HashMapTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
HashMap<String,String> dictionaryMap = new HashMap();
dictionaryMap.put("apple","苹果");
dictionaryMap.put("banana","香蕉");
dictionaryMap.remove("apple");
}
}
5.someMap1.putAll( someMap2 ),这边的somMap2必须和someMap1是同类型的,也就是Entry类型要相同(就是 <key,Value>的映射类型要相同)
package Test;
import java.util.HashMap;
import java.util.Map;
public class HashMapTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Map<String,String> dicMap = new HashMap();
dicMap.put("apple","苹果");
dicMap.put("banana","香蕉");
Map <String ,String> dicMap2 = new HashMap();
dicMap2.put("apple", "苹果2");
dicMap2.put("watermelon", "西瓜");
dicMap.put("banana","香蕉2");
dicMap.putAll(dicMap2);
System.out.println(dicMap);
}
}
/*
运行结果:
{banana=香蕉2, apple=苹果2, watermelon=西瓜}
*/
大家会发现,把dicMap2合并到dicMap后,虽然两个HashMap中都有 <“apple” ,>的映射,但是一个Map中一个key值只能映射一个value, 那"apple"到底映射哪个呢?答案是: 会被后面key值相同的映射覆盖。所以 <"apple" , >最后的映射是 <"apple" ,“苹果2”>。
6.clear(),用于清空容器
package Test;
import java.util.HashMap;
import java.util.Map;
public class HashMapTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Map<String,String> dicMap = new HashMap();
dicMap.put("apple","苹果");
dicMap.put("banana","香蕉");
System.out.println("清空前:");
System.out.println(dicMap);
dicMap.clear();
System.out.println("清空后:");
System.out.println(dicMap);
}
}
/*
运行结果:
清空前:
{banana=香蕉, apple=苹果}
清空后:
{}
*/
五.HashMap的遍历(也是Map的遍历方法)
方法a. 取出key集合
1.通过 setKey()返回一个key的Set -----称为mySet
2.调用mySet.iterator()返回一个对应类型的迭代器
3.通过迭代器遍历
package Test;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class HashMapTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Map<String,String> dicMap = new HashMap();
dicMap.put("apple","苹果");
dicMap.put("banana","香蕉");
Set<String> mySet = dicMap.keySet();
Iterator <String> it = mySet.iterator();
while(it.hasNext()) {
String curKey = it.next(); //获取当前的key
String curValue = dicMap.get(curKey); //获取当前key对应的value
System.out.println("curKey is: " + curKey + " curValue is:" + curValue);
}
}
}
/*
运行结果:
curKey is: banana curValue is:香蕉
curKey is: apple curValue is:苹果
*/
方法b. 取出键值集合
先了解一下什么是Map.Entry:
Map是java中的接口,而Map.Entry是Map的一个内部接口。entrySet()的返回值是返回一个Set集合,此集合的中元素的类型
为Map.Entry< >。
1.取出键值集合
2.生成上述集合的一个迭代器
3.通过迭代器遍历时:
取出当前键值
取出当前键值的Key
取出当前键值的Value
package Test;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class HashMapTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Map<String,String> dicMap = new HashMap();
dicMap.put("apple","苹果");
dicMap.put("banana","香蕉");
//取出Map.Entry<String,String>的键值set
Set<Map.Entry<String,String>> mySet = dicMap.entrySet();
//返回该Set的迭代器
Iterator it = mySet.iterator();
while(it.hasNext()) {
//取出当前遍历到的Map.Entry
Map.Entry<String ,String> curEntry = (Map.Entry)it.next();
//取出当前Entry的key
String curKey = curEntry.getKey();
//取出当前Entry的Value
String curValue =curEntry.getValue();
System.out.println("curKey is: " + curKey + " curValue is:" + curValue);
}
}
}
/*
运行结果:
curKey is: banana curValue is:香蕉
curKey is: apple curValue is:苹果
*/
注:通过学习得知,entrySet()遍历Map的速度比keySet()的速度遍历Map的速度慢了很多。为了提高性能,以后多考虑用entrySet()方式来进行遍历。