2021-11-07 HashMap的操作,总结一下

每次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);
             }
         }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值