每次HashMap的操作都要查,终于抽时间总结一下
一、HashMap的基本操作
1、创建
HashMap<Integer,String> map = new HashMap<>();
2、添加
//时间复杂度O(1),通过哈希函数获得内存地址,然后放入内存
//map.put(key,value)
map.put(1,"lihua");
3、更新
map.put(1,"huahua");
4、删除元素
//时间复杂度 O(1),直接找到元素,然后操作
map.remove(1)
5、获取元素
//时间复杂O(1)
//key可以通过哈希函数直接获得
//map.get(key)
map.get(1);
//值为对应的value
6、检查key是否存在
//返回true or false
map.containsKey(1);
二、HashMap获取<key,value>
1、迭代器
(a)
//效率更高一点
HashMap<String,String> map = new HashMap<>();
Iterator iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Object key = entry.getKey();
Object val = entry.getValue();
}
(b)
Map map = new HashMap();
Iterator iter = map.keySet().iterator();
while (iter.hasNext()) {
Object key = iter.next();
Object val = map.get(key);
}
2、foreach
(a)
HashMap<String,String> map = new HashMap<>();
Set<Entry<String, Integer>> en = map.entrySet();
for(Entry<String, Integer> entry : en) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
(b)
Map<String, String> map = new HashMap<String, String>();
for (String key : map.keySet()) {
map.get(key);
}
这里的map.entrySet()要深挖一下
HashMap这个方法的entrySet()方法,这个方法返回返回的是一个Set对象,很多人以为返回的是一个包含了Map里面所有键值对的一个集合对象,这个理解不准确,怎么说呢,通过这个Set对象,我们确实可以获取到Map里面存放的所有键值对,但是这个集合对象本身是不存放数据的,它只是助于我们遍历Map中的数据,类似于Iterator。其实HashMap的key并没有加入到EntrySet集合中,而是在遍历的时候,使用迭代器对key进行的遍历。这是结论。下面我们看一下原因和过程。
entrySet()源码:
public Set<Entry<K, V>> entrySet() {
Set var1;
return (var1 = this.entrySet) == null ? (this.entrySet = new HashMap.EntrySet()) : var1;
}
HashMap内部维护的一个引用entrySet,这个应用是EntrySet类型的。但是我们在HashMap的源码中找一下entrySet是何时填充数据的,然后再来看一下EntrySet的类定义:
final class EntrySet extends AbstractSet<Entry<K, V>> {
EntrySet() {
}
public final int size() {
return HashMap.this.size;
}
public final void clear() {
HashMap.this.clear();
}
public final Iterator<Entry<K, V>> iterator() {
return HashMap.this.new EntryIterator();
}
public final boolean contains(Object var1) {
if (!(var1 instanceof Entry)) {
return false;
} else {
Entry var2 = (Entry)var1;
Object var3 = var2.getKey();
HashMap.Node var4 = HashMap.this.getNode(HashMap.hash(var3), var3);
return var4 != null && var4.equals(var2);
}
}
public final boolean remove(Object var1) {
if (var1 instanceof Entry) {
Entry var2 = (Entry)var1;
Object var3 = var2.getKey();
Object var4 = var2.getValue();
return HashMap.this.removeNode(HashMap.hash(var3), var3, var4, true, true) != null;
} else {
return false;
}
}
public final Spliterator<Entry<K, V>> spliterator() {
return new HashMap.EntrySpliterator(HashMap.this, 0, -1, 0, 0);
}
public final void forEach(Consumer<? super Entry<K, V>> var1) {
if (var1 == null) {
throw new NullPointerException();
} else {
HashMap.Node[] var2;
if (HashMap.this.size > 0 && (var2 = HashMap.this.table) != null) {
int var3 = HashMap.this.modCount;
for(int var4 = 0; var4 < var2.length; ++var4) {
for(HashMap.Node var5 = var2[var4]; var5 != null; var5 = var5.next) {
var1.accept(var5);
}
}
if (HashMap.this.modCount != var3) {
throw new ConcurrentModificationException();
}
}
}
}
}
EntrySet类中的迭代器函数,返回的是一个Iterator<Entry<K, V>>类的对象即HashMap.this.new EntryIterator()。这个迭代器其实就是对调用者这个对象进行操作。也就是说,当使用迭代器遍历set内的元素时,通过EntrySet类的迭代器,会保证能够依次获取到HashMap的节点的键值对的集合,这就是我们遍历EntrySet的过程的实质。
HashMap.entrySet( )本身并没有难度,该方法并不是返回一个存储数据的集合,它只是一个视图窗口。
keySet()的方法也类似,可以看这篇博客源码解析HashMap的keySet()方法
三、通过value获取key
方法一:
1、
根据value值获取到对应的一个key
public String getKey(HashMap<String,String> map,String value){
String key = null;
//Map,HashMap并没有实现Iteratable接口.不能用于增强for循环.
for(String getKey: map.keySet()){
if(map.get(getKey).equals(value)){
key = getKey;
}
}
return key;
//这个key肯定是最后一个满足该条件的key.
}
2、根据value值获取到对应的所有的key值
public List<String> getKeyList(HashMap<String,String> map,String value){
List<String> keyList = new ArrayList();
for(String getKey: map.keySet()){
if(map.get(getKey).equals(value)){
keyList.add(getKey);
}
}
return keyList;
}
方法二:
public ArrayList<String> getKey(String value) {
ArrayList<String> keyList = new ArrayList<String>();
String key = null;
Set<Entry<String, String>> set = map.entrySet();
Iterator it = set.iterator();
while (it.hasNext()) {
Map.Entry<String, String> entry = (Map.Entry<String, String>) it.next();
if (entry.getValue().equals(value)){
key = (String) entry.getKey();
keyList.add(key);
}
}