当前位置: 首页 > news >正文

HashMap的简单实现

 基本概念

Map 别名映射表,也叫关联数组,基本思想是它维护的键-值(对)关联,因此可以用键查找值,也有放入键值的操作,下面根据定义自己来实现一个Map,首先应该想到的是数组,因为大多数Java集合类底层都是基于数组和链表的,这里我给它命名叫做 MapVersion01

 1 public class MapVersion01<K,V> {
 2     //存储每一个键值对的数组
 3     private Object[][] pairs;
 4     //数组的容量
 5     private int index;
 6 
 7     public MapVersion01(int capacity) {
 8         this.pairs = new Object[capacity][2];
 9     }
10 
11     /**
12      * 插入的方法
13      * @param key
14      * @param value
15      */
16     public void  put(K key, V value) {
17         if(index >= pairs.length)
18             throw new IndexOutOfBoundsException();
19         pairs[index++] = new Object[]{key, value};
20     }
21 
22     /**
23      * 查找方法
24      * @param key
25      * @return
26      */
27     public V get(K key) {
28         for(int i = 0 ; i < index ; i++) {
29             if(key.equals(pairs[i][0]))
30                 return (V)pairs[i][1];
31         }
32         return null;
33     }
34 
35     @Override
36     public String toString() {
37         StringBuilder sb = new StringBuilder();
38         for(int i = 0 ; i < index ; i ++) {
39             sb.append(pairs[i][0]).toString();
40             sb.append(" : ");
41             sb.append(pairs[i][1].toString());
42             if(i < index - 1) {
43                 sb.append("\n");
44             }
45         }
46         return sb.toString();
47     }
48 
49     public static void main(String[] args) {
50         MapVersion01<Integer,String> map = new MapVersion01<Integer,String>(10);
51         map.put(1,"111");
52         map.put(2,"222");
53         map.put(3,"333");
54         map.put(4,"444");
55         map.put(5,"555");
56         map.put(6,"666");
57         System.err.println(map);
58     }
单元测试结果:

这里为了方便查看,重写了toString方法,打印出每一个键值对儿,乍一看,实现起来貌似很简单,再看一下Map接口,好像少了点什么。对了,少了2样东西:

  1. 遍历hash表取键值对的方法;
  2. 分别得到所有键的集合、值的集合;

这2个问题应该很好实现,下面是我实现的:

 1 public Set<K> keySet() {
 2     Set<K> keySet = new HashSet<K>();
 3     if (pairs.length > 0) {
 4         for (int i = 0; i < index; i++) {
 5             K key = (K) pairs[i][0];
 6             keySet.add(key);
 7         }
 8     }
 9     return keySet;
10 }
11 
12 public Set<V> values() {
13     Set<V> values = new HashSet<V>();
14     if (pairs.length > 0) {
15         for (int i = 0; i < index; i++) {
16             V value = (V) pairs[i][1];
17             values.add(value);
18         }
19     }
20     return values;
21 }
22 
23 public Set<Entry<K, V>> entrySet() {
24     Set<Entry<K, V>> set = new HashSet<Entry<K, V>>();
25     if (pairs.length > 0) {
26         for (int i = 0; i < index; i++) {
27             K key = (K) pairs[i][0];
28             V value = (V) pairs[i][1];
29             Entry<K, V> entry = new Entry<K, V>(key, value);
30             set.add(entry);
31         }
32     }
33     return set;
34 }
35 
36 //键值对存放在一起的映射对象
37 private static class Entry<K, V> {
38     private K key;
39     private V value;
40 
41     public Entry(K key, V value) {
42         this.key = key;
43         this.value = value;
44     }
45 
46     public K getKey() {
47         return key;
48     }
49 
50     public void setKey(K key) {
51         this.key = key;
52     }
53 
54     public V getValue() {
55         return value;
56     }
57 
58     public void setValue(V value) {
59         this.value = value;
60     }
61 
62     @Override
63     public int hashCode() {
64         return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode());
65     }
66 
67     @Override
68     public boolean equals(Object obj) {
69         if (!(obj instanceof Entry))
70             return false;
71         Entry<K, V> me = (Entry<K, V>) obj;
72         return (me.getKey() == null ? key == null : me.getKey().equals(key)) &&
73                 (me.getValue() == null ? value == null : me.getValue().equals(value));
74     }
75 }

 

转载于:https://www.cnblogs.com/blentle/p/6604955.html

相关文章:

  • 【后缀自动机】hihocoder1441 后缀自动机一·基本概念
  • kafka之zk搭建
  • 机器学习 —— 基础整理(一)贝叶斯决策论;二次判别函数;贝叶斯错误率;生成式模型的参数方法...
  • C# Int转Enum
  • 开启TDE的RDS SQL Server还原到本地环境
  • 如何使用thinkphp的model来验证前端表单?
  • 磁盘文件系统2
  • 201521123009 《Java程序设计》第6周学习总结
  • Java深入 - 深入理解Java集合
  • [转] CSSOM视图模式(CSSOM View Module)相关整理
  • 批处理数字前加0
  • MySQL innodb_table_stats表不存在的解决方法
  • 鬼谷子的局 有感
  • bash脚本总结1:[[:not found 错误
  • Maven(一)-- 基础知识
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • 345-反转字符串中的元音字母
  • Docker入门(二) - Dockerfile
  • ES6语法详解(一)
  • Intervention/image 图片处理扩展包的安装和使用
  • leetcode388. Longest Absolute File Path
  • Linux下的乱码问题
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • Nodejs和JavaWeb协助开发
  • node学习系列之简单文件上传
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • 计算机常识 - 收藏集 - 掘金
  • 精彩代码 vue.js
  • 快速构建spring-cloud+sleuth+rabbit+ zipkin+es+kibana+grafana日志跟踪平台
  • 两列自适应布局方案整理
  • 浏览器缓存机制分析
  • 每天10道Java面试题,跟我走,offer有!
  • 我是如何设计 Upload 上传组件的
  • 想使用 MongoDB ,你应该了解这8个方面!
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • Java数据解析之JSON
  • 摩拜创始人胡玮炜也彻底离开了,共享单车行业还有未来吗? ...
  • 容器镜像
  • 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解 ...
  • ​LeetCode解法汇总2304. 网格中的最小路径代价
  • ​渐进式Web应用PWA的未来
  • ​决定德拉瓦州地区版图的关键历史事件
  • # 达梦数据库知识点
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • (12)Hive调优——count distinct去重优化
  • (2020)Java后端开发----(面试题和笔试题)
  • (3)选择元素——(14)接触DOM元素(Accessing DOM elements)
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (板子)A* astar算法,AcWing第k短路+八数码 带注释
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (附源码)springboot优课在线教学系统 毕业设计 081251
  • (附源码)springboot猪场管理系统 毕业设计 160901