Java04 容器(之底层原理b)

Java04 容器(之底层原理b)

在这里插入图片描述

 * HashMap底层实现使用了哈希表(数据结构)
 * 基本:数组Array+链表Linked(结合,取长补短)
 *               链表长度大于8时,链表转换为红黑树(提高查询效率)
 *               约定:两个内容相同(equals=True)的对象有相等的哈希code
 *
 *
 * 底层介绍:
 * HashMap的结构(也称:Entry位桶数组)
 * 0  |hash-key-value-next|-->|hash-key-value-next|-|hash-key-value-next|
 * 1  |hash-key-value-next|-->|hash-key-value-next|-|hash-key-value-next|
 * ...
 * 15 |hash-key-value-next|-->|hash-key-value-next|-|hash-key-value-next|
 *
 * 存储具体过程:
 * (哈希算法1)相除取余法:使用key对象的哈希code,数组长度约定为2的整数幂,默认为16(当达到0.75*数组长度,数组大小扩容*2*      哈希code除以数组长度16,得到的余数为哈希值,作为上面的16个分组中的1个,整个数据块接在尾端next上面
 * 改进:哈希code按位与(数组长度-1)
 *     淘汰的a, 除于哈希值,退化为链表;
 *    淘汰的b, 除于1,退化为数组

一个简单的Hashmap例子,只有简单的插入功能(实现了相同key覆盖)哦,(想要其他功能打印或者读取值的可以再补充),效果如下:
在这里插入图片描述

public class SxtHashMap01 {

    Node2[] tabel;
    int size;//存放键值对个数

    //构造器
    public SxtHashMap01(){
        tabel = new Node2[16];
    }

    //方法1:输入方法
    public void put(Object key, Object value){
        Node2 newNode = new Node2();

        /**
         * 步骤1:定义插入的新节点的信息
         */
        //Node2类里面4个属性,分别描述属性获取值的方法
        newNode.hash = myHash(key.hashCode(),tabel.length);//通过方法myHash获得
        //通过赋值符=获得
        newNode.key = key;
        newNode.value = value;
        newNode.next = null;

        /**
         * 步骤2:根据信息,进行遍历(利用不实际存在的辅助节点temp和iterLast)
         */
        boolean keyno_Repeat = true;
        Node2 temp = tabel[newNode.hash];

        Node2 iterLast = null;//正在遍历最后一个元素

        if(temp==null){//如果此处数组元素为空,则直接将新节点放进去
            tabel[newNode.hash] = newNode;
            size++;
        }else{//如果此处数组元素不为空,遍历该数组对应的列表
            while (temp!=null){
                //key如果重复,则覆盖
                if(temp.key.equals(key)){
                    keyno_Repeat = false;
                    System.out.println("重复之前的节点: "+temp.key+"="+temp.value);
                    temp.value=value;
                    System.out.println("重复,利用新节点覆盖: "+temp.key+"="+temp.value);
                    break;//直接跳出循环
                }else{
                    //key不重复,则遍历下一个(跳到循环再判断是否key重复)
                    iterLast = temp;
                    temp=temp.next;
                }

                //key如果没有重复,插入新节点
                if(keyno_Repeat) {
                    iterLast.next = newNode;
                    System.out.println("abc"+iterLast.next);
                    size++;
                }

            }
        }
    }

    /**
     * 利用hashcode得到hash值
     * @param v hashcode
     * @param length 数组长度
     * @return hash值
     */
    //方法1.1:读取Hash值方法
    public int myHash(int v,int length){
        System.out.println("put新节点:");
        System.out.println("hash in myHash按位与:"+(v&(length-1)));//效率更高
        System.out.println("hash in myHash除以:"+(v%(length)));//两种都是为了分散存储
        return v&(length-1);
    }

    public static void main(String[] args) {
        SxtHashMap01 m = new SxtHashMap01();
        m.put(10,"aa");
        m.put(20,"bb");
        m.put(30,"cc");
        m.put(20,"ssss");
        m.put(50,"hhh");
        System.out.println("存放键值对个数"+m.size);
        System.out.println(m);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值