Map原理解析01----数组与单链表

背景

说到Map,估计作为一个java从业者,大家应该都不陌生。其实早在两年前就有面试官问我HashMap的实现及原理了。当时作为一个从业不到两年的我,很流利的回答了原理是数组加链表。但是何为数组何为链表,HashMap初始化究竟做了那些事情等等,其实我根本讲不清楚讲不明白。这件事其实也一直耿耿于怀我心中。每当有点时间的时候,我都会尝试性的去看看hashmap的源码,但是鉴于实力水平及个人资质以及花在上面的时间,直到今天,我也只能是浅谈一下Map。接下来的几篇文章我将从以下几个方面来剖析HashMap

  • 什么是数组及链表
  • 实现一个类似HashMap的容器类
  • 什么是红黑树
  • Map抽象接口的定义
  • HashMap初始化做了那些事情
  • HashMap的put方法详解
  • HashMap的get方法详解
  • HashMap的继承及实现关系
  • CurrentHashMap线程安全的实现机制

这一片我们单纯介绍数组及链表即可。

什么是数组

定义
数组指的是一组相关类型的变量的集合,是一种容器,可以同时存放多个数据值

特点

  • 查找速度快,随机访问性强
  • 数组中多个数据,类型必须统一
  • 数组的长度在程序运行期间不可改变
  • 插入和删除效率低
  • 可能浪费内存,即数组长度使用不完
  • 内存空间要求高,必须有足够的连续内存空间

从特点我们可知数组访问速度快,但是插入慢。为什么这么说呢。当插入元素时我们需要移动大量元素,在内存中空出一个元素的空间,然后将要增加的元素放在其中,因此慢。删除同理。又由于每个元素占用内存相同,可以通过下标迅速访问数组中任何元素,所以快。

什么是链表

定义
链表是把每个数据分为一个类,然后通过next指针域连接起来的表。这么说我自己也一脸懵逼。还是举个例子吧(人懒就直接用HashMap里面的Node节点了,别踩)

static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        V value;
        Node<K,V> next;

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

        public final K getKey()        { return key; }
        public final V getValue()      { return value; }
        public final String toString() { return key + "=" + value; }

        public final int hashCode() {
            return Objects.hashCode(key) ^ Objects.hashCode(value);
        }

        public final V setValue(V newValue) {
            V oldValue = value;
            value = newValue;
            return oldValue;
        }

        public final boolean equals(Object o) {
            if (o == this)
                return true;
            if (o instanceof Map.Entry) {
                Map.Entry<?,?> e = (Map.Entry<?,?>)o;
                if (Objects.equals(key, e.getKey()) &&
                        Objects.equals(value, e.getValue()))
                    return true;
            }
            return false;
        }
    }

嗯嗯,很好。就是这样子。简单剖析下这个类吧,含有hash,key,value,next4个属性。setValue(),getKey(),getValue(),hashCode(),toString()几个方法。
当创建node节点时,需要指定他的key,value,next这几个值。而next又是一个node,依次链接就得到了一个小火车。这就是单链表。
链表的特点

  • 每一个数据都保存了下一个数据的内存地址,通过这个地址找到下一个数据。 第一个人知道第二个人的座位号,第二个人知道第三个人的座位号……

  • 增加数据和删除数据很容易。 再来个人可以随便坐,比如来了个人要做到第三个位置,那他只需要把自己的位置告诉第二个人,然后问第二个人拿到原来第三个人的位置就行了。其他人都不用动。

  • 查找数据时效率低,因为不具有随机访问性,所以访问某个位置的数据都要从第一个数据开始访问,然后根据第一个数据保存的下一个数据的地址找到第二个数据,以此类推。 要找到第三个人,必须从第一个人开始问起

  • 不指定大小,扩展方便。链表大小不用定义,数据随意增删

不难发现链表插入删除等操作容易,遍历就麻烦。一旦长了就只有一个一个走。

好的,链表与数组暂时介绍到这里。下一篇我们将会使用数组和链表实现一个类似HashMap的容器类

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值