@Java 300 学习总结

HashMap底层采用实现采用了哈希表,结合了“数组和链表”。

原理如图

一、定义HashMap类。

首先需要定义一个节点来存储数据,构成链表结构。

public class Node {
int hash;
Object key;
Object value;
Node next;
}
public class ggHashMap {
Node[] table; //位桶数组,用于存放链表的第一个节点
int size;
public ggHashMap() {
super();
table = new Node[16]; //默认初始为16
} public static void main(String[] args) {
ggHashMap m1 = new ggHashMap();
System.out.println();
}
}

二、实现put方法,往HashMap里添加元素

每一个节点存放进HashMap里,首先根据key继续Hash值,以此确定插入的位置。


public int myHash(int v,int length) {
return v&(length -1);//根据Hash值与位桶数组长度,进行位运算,保证插入元素的随机
//位运算与取模运算效果相同,但是效率更高
} public void put(Object key, Object value) {
Node newNode = new Node();
newNode.hash = myHash(key.hashCode(),table.length);
//根据key的值取hash值,hashCode()为对象默认存在的方法
newNode.key = key;
newNode.value = value;
newNode.next = null; Node temp = table[newNode.hash];//指向要插入的数组位置
Node iterLast = null;//正在遍历的最后一个元素
boolean keyRepeat = false;//判定元素key值是否相同被覆盖
if(temp == null) { //数组元素为空
table[newNode.hash] = newNode;
}
else { //不为空的情况
while(temp!=null) { //遍历该链表 //判断key是否重复
if(temp.key.equals(key)) {
keyRepeat = true;
temp.value = value;
break; //找到重复结束遍历
}else {
iterLast = temp; //iterLast跟着temp向后移一位
temp = temp.next;
}
}
if(!keyRepeat) {
iterLast.next = newNode; //没有发现重复,最后一位的next,指向新节点
}
}
}

三、实现toString方法

利用可以自动扩增的StringBuilder对象,遍历每个节点,可实现数据的HashMap的字符串。

public String toString() {
StringBuilder sb = new StringBuilder("{");
for(int i = 0;i < table.length;i++) {
Node temp = table[i];
while(temp!=null) {
sb.append(temp.key+":"+temp.value + ",");
temp = temp.next;
}
}
sb.setCharAt(sb.length()-1, '}');//将最后一个,号,转为}
return sb.toString();
}

四、实现get方法,根据key获得value

根据key值计算hash数值,指针指向数组索引值和hash值相等的节点,遍历该节点的链表,找到key值相等的节点,返回value值

public Object get(Object key) {
int hash = myHash(key.hashCode(), table.length);
Object value = null;
Node temp = table[hash];
while(temp!=null) {
if(temp.key.equals(key)) {
value = temp.value;
break;
}else {
temp = temp.next;
}
}
return value;
}

五、增加泛型

public class Node2<K,V> {
int hash;
K key;
V value;
Node2 next;
}
public class ggHashMap4<K,V> {
public V get(K key) { }
public void put(K key, V value) { }
}

Java手写简单HashMap一(包括增加,查找,toString,泛型)的更多相关文章

  1. Java手写简单Linkedlist一(包括增加,插入,查找,toString,remove功能)

    @Java300 学习总结 一.自定义节点 LinkList底层为双向链表.特点为查询效率低,但增删效率高,线程不安全. 链表数据储存在节点,且每个节点有指向上个和下个节点的指针. 创建ggLinke ...

  2. 利用Java手写简单的httpserver

    前言: 在看完尚学堂JAVA300中讲解如何实现一个最简单的httpserver部分的视频之后, 一.前置知识 1.HTTP协议 当前互联网网页访问主要采用了B/S的模式,既一个浏览器,一个服务器,浏 ...

  3. 教你如何使用Java手写一个基于链表的队列

    在上一篇博客[教你如何使用Java手写一个基于数组的队列]中已经介绍了队列,以及Java语言中对队列的实现,对队列不是很了解的可以我上一篇文章.那么,现在就直接进入主题吧. 这篇博客主要讲解的是如何使 ...

  4. java 手写 jvm高性能缓存

    java 手写 jvm高性能缓存,键值对存储,队列存储,存储超时设置 缓存接口 package com.ws.commons.cache; import java.util.function.Func ...

  5. java手写多级缓存

    多级缓存实现类,时间有限,该类未抽取接口,目前只支持两级缓存:JVM缓存(实现 请查看上一篇:java 手写JVM高性能缓存).redis缓存(在spring 的 redisTemplate 基础实现 ...

  6. 不使用Tomcat,手写简单的web服务

    背景: 公司使用的YDB提供了http的查询数据库服务,直接通过url传入sql语句查询数据-_-||.ydb的使用参照:https://www.cnblogs.com/hd-zg/p/7115112 ...

  7. 手写简单call,apply,bind

    分析一下call的使用方法:call是显示绑定this指向,然后第一个参数是你所指向的this对象,后面跟着多个参数,以逗号隔开 function sum(num1,num2){ return num ...

  8. 手写简单的jq雪花飘落

    闲来无事,准备写个雪花飘落的效果,没有写太牛逼的特效,极大的简化了代码量,这样容易读取代码,用起来也很简单,对于那些小白简直是福利啊,简单易读易学.先直接上代码吧,然后再一一讲解,直接复制粘贴就可以拿 ...

  9. Java:手写幼儿园级线程安全LRU缓存X探究影响命中率的因素

    最近遇到一个需求,需要频繁访问数据库,但是访问的内容只是 id + 名称 这样的简单键值对. 频繁的访问数据库,网络上和内存上都会给数据库服务器带来不小负担. 于是打算写一个简单的LRU缓存来缓存这样 ...

随机推荐

  1. Linux之基础命令

    常用命令 查看ip地址的两种方式 ifconfig ip addr show Linux的两种ip地址: 127.0.0.1 本机回环地址 0.0.0.0 全网地址/绑定所有网卡/所有地址 Linux ...

  2. Zhejiang Provincial Collegiate Programming Contest + ZOJ Monthly

    题目链接:https://vjudge.net/contest/152802#overview. 前五题以前做过了.不过还是没能全A= =. 前三题水题,略过. 第四题是找规律,暴力打表找一下循环节即 ...

  3. Flask 编写一个授权登录验证的模块(一)

    看一个关于授权登陆的简易模块,觉得挺不错,学习学习. 1.登录的逻辑:如果用户名和密码正确,就返回 token .2.生成 token 的逻辑,根据用户名,随机数,当前时间 + 2 小时3.然后放在 ...

  4. 完全背包---P1679 神奇的四次方数

    P1679 神奇的四次方数 题解 一看这就是个完全背包 m最多不会超过18^4,所以我们把x^4用数组存起来,然后考虑如何填满m,注意存到18^4,不然会像我一样RE... 那么问题就转化成完全背包问 ...

  5. java Annotation 注解的使用

    源码地址:https://github.com/yylxy/JavaAnnotationTest.git java Annotation 注解的使用 ,代码中有详细的注释.是用AndroidStudi ...

  6. leetcode 96. Unique Binary Search Trees 、95. Unique Binary Search Trees II 、241. Different Ways to Add Parentheses

    96. Unique Binary Search Trees https://www.cnblogs.com/grandyang/p/4299608.html 3由dp[1]*dp[1].dp[0]* ...

  7. C之堆栈

    栈* 自动申请,自动释放* 大小固定,内存空间连续* 从栈上分配的内存叫静态内存 堆* 程序员自己申请* new/malloc* 大小取决于虚拟内存的大小,内存空间不连续* java中自动回收,C中需 ...

  8. java time

    package cn.itcast_04;       import java.text.SimpleDateFormat;   import java.util.Date;       public ...

  9. 11 Flutter仿京东商城项目 商品列表页面二级筛选导航布局

    ProductList.dart import 'package:flutter/material.dart'; import '../services/ScreenAdaper.dart'; imp ...

  10. PAT 甲级1025 PAT Ranking (25 分)(结构体排序,第一次超时了,一次sort即可小技巧优化)

    题意: 给定一次PAT测试的成绩,要求输出考生的编号,总排名,考场编号以及考场排名. 分析: 题意很简单嘛,一开始上来就,一组组输入,一组组排序并记录组内排名,然后再来个总排序并算总排名,结果发现最后 ...