实现一个简单的散列表(HashMap)
下面参考java.util.HashMap<K, V>,写了一个简单的散列表,只实现了其中的put和get方法,使用链接法"碰撞冲突"。代码最后,自定义了一个People类,并覆盖了equals,hashCode,toString方法,实现了Comparable接口。利用People类检验散列表的正确性,并利用Arrays或Collections对People进行排序。
- import java.util.Arrays;
- //import java.util.Collections;
- class ListNode<K, V> {//为解决"碰撞冲突",使用链接法的结点结构。
- ListNode<K, V> next;
- K key;
- V val;
- public ListNode(K k, V v) {
- key = k; val = v;
- }
- }
- class HashMap<K, V> {//一个简单的散列表,实现了put和get方法。
- ListNode<K, V>[] table = null; //构造一个散列表:一个存放链表的数组。
- static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; //
- int size;
- public HashMap() {
- setUp(DEFAULT_INITIAL_CAPACITY);
- }
- public HashMap(int capacity) {
- setUp(capacity);
- }
- @SuppressWarnings("unchecked")
- public void setUp(int capacity) {
- size = capacity;
- table = (ListNode<K, V>[])new ListNode[size];
- }
- public int hash(Object k) { //散列函数
- return Math.abs(k.hashCode() % table.length);
- }
- public V put(K key, V value) { //return the old value
- if(key == null)
- return putForNullKey(value);
- int i = hash(key);
- for(ListNode<K, V> e = table[i]; e != null; e = e.next) {
- if(e.key == key || key.equals(e.key)) {
- V oldVal = e.val;
- e.val = value;
- return oldVal;
- }
- }
- addListNode(i, key, value);
- return null;
- }
- public V putForNullKey(V value) {
- for (ListNode<K, V> e = table[0]; e != null; e = e.next) { // 只考虑table中下标为0的位置。
- if(e.key == null) {
- V oldVal = e.val;
- e.val = value;
- return oldVal;
- }
- }
- table[0] = new ListNode<>(null, value);
- return null;
- }
- public V get(K key) {
- if(key == null)
- return getForNullKey();
- int i = hash(key);
- for(ListNode<K, V> e = table[i]; e != null; e = e.next) {
- if(e.key == key || key.equals(e.key))
- return e.val;
- }
- return null;
- }
- public V getForNullKey() {
- for(ListNode<K, V> e = table[0]; e != null; e = e.next) {
- if(e.key == null)
- return e.val;
- }
- return null;
- }
- public void addListNode(int i, K key, V value) {
- ListNode<K, V> tmp = table[i];
- table[i] = new ListNode<>(key, value);
- table[i].next = tmp;
- }
- }
- class People implements Comparable<People> { // 自定义People类,并覆盖了equals,hashCode,toString方法,实现了Comparable接口。
- String name;
- int age;
- public People(String n, int a) {
- name = n; age = a;
- }
- @Override
- public boolean equals(Object obj) {
- if(this == obj)
- return true;
- if(!(obj instanceof People))
- return false;
- return this.name.equals(((People)obj).name) && this.age == ((People)obj).age;
- }
- @Override
- public int hashCode() {
- return name.hashCode()*37 + age;
- }
- @Override
- public String toString() {
- return name + "," + age;
- }
- @Override
- public int compareTo(People o) {
- return this.age - o.age;
- }
- }
- public class TestClass { //测试类
- public static void main(String[] args) {
- People[] people = new People[] { new People("xue", 25),
- new People("hong", 20), new People("jun", 21)};
- Arrays.sort(people);
- // Collections.sort(Arrays.asList(people));
- for (People peo : people) {
- System.out.println(peo);
- }
- HashMap<People, Integer> hm = new HashMap<People, Integer>();
- for (int i = 0; i < people.length; i++) {
- hm.put(people[i], i);
- }
- for (int i = 0; i < people.length; i++) {
- System.out.println(hm.get(people[i]));
- }
- }
- }
实现一个简单的散列表(HashMap)的更多相关文章
- 【Java】 大话数据结构(13) 查找算法(4) (散列表(哈希表))
本文根据<大话数据结构>一书,实现了Java版的一个简单的散列表(哈希表). 基本概念 对关键字key,将其值存放在f(key)的存储位置上.由此,在查找时不需比较,只需计算出f(key) ...
- HashMap、lru、散列表
HashMap HashMap的数据结构:HashMap实际上是一个数组和链表("链表散列")的数据结构.底层就是一个数组结构,数组中的每一项又是一个链表. hashCode是一个 ...
- 用js来实现那些数据结构12(散列表)
上一篇写了如何实现简单的Map结构,因为东西太少了不让上首页.好吧... 这一篇文章说一下散列表hashMap的实现.那么为什么要使用hashMap?hashMap又有什么优势呢?hashMap是如何 ...
- 散列表和JAVA中的hash
引文 hello,今天写的数据结构是散列表(hash表),也算是一种基础数据结构了吧.学过计算机的人大概都能说出来这是个以空间换时间的东西,那么具体怎么实现的是今天要讨论的问题. 为什么需要它?主要还 ...
- 哈希表(散列表),Hash表漫谈
1.序 该篇分别讲了散列表的引出.散列函数的设计.处理冲突的方法.并给出一段简单的示例代码. 2.散列表的引出 给定一个关键字集合U={0,1......m-1},总共有不大于m个元素.如果m不是很大 ...
- Python与数据结构[4] -> 散列表[0] -> 散列表与散列函数的 Python 实现
散列表 / Hash Table 散列表与散列函数 散列表是一种将关键字映射到特定数组位置的一种数据结构,而将关键字映射到0至TableSize-1过程的函数,即为散列函数. Hash Table: ...
- Python与数据结构[4] -> 散列表[2] -> 开放定址法与再散列的 Python 实现
开放定址散列法和再散列 目录 开放定址法 再散列 代码实现 1 开放定址散列法 前面利用分离链接法解决了散列表插入冲突的问题,而除了分离链接法外,还可以使用开放定址法来解决散列表的冲突问题. 开放定 ...
- 数据结构---散列表查找(哈希表)概述和简单实现(Java)
散列表查找定义 散列技术是在记录的存储位置和它的关键字之间建立一个确定的对应关系f,是的每个关键字key对应一个存储位置f(key).查找时,根据这个确定的对应关系找到给定值的key的对应f(key) ...
- Java HashMap源码分析(含散列表、红黑树、扰动函数等重点问题分析)
写在最前面 这个项目是从20年末就立好的 flag,经过几年的学习,回过头再去看很多知识点又有新的理解.所以趁着找实习的准备,结合以前的学习储备,创建一个主要针对应届生和初学者的 Java 开源知识项 ...
随机推荐
- java中 equals和==区别
一.java当中的数据类型和“==”的含义: 基本数据类型(也称原始数据类型) :byte,short,char,int,long,float,double,boolean.他们之间的比较,应用双等号 ...
- Dart编程语言从基础到进阶1
Dart编程语言从基础到进阶Dart的语言的发展史以及Dart能做什么未来发展怎么样等等问题我们在这里是不讨论的.我相信既然选择了来学习它,那你内心基本已经认可了它,所以我们废话不多说直接进入主题. ...
- Linux命令实战(一)
1.pwd(printing working directory)打印当前工作目录路径 [root@test sysconfig]# pwd /etc/sysconfig 2.ls(list)列出当前 ...
- DEX文件解析---1、dex文件头解析
DEX文件解析---1.dex文件头解析 一.dex文件 dex文件是Android平台上可执行文件的一种文件类型.它的文件格式可以下面这张图概括: dex文件头一般固定为0x70个字 ...
- 还看不懂同事的代码?超强的 Stream 流操作姿势还不学习一下
Java 8 新特性系列文章索引. Jdk14都要出了,还不能使用 Optional优雅的处理空指针? Jdk14 都要出了,Jdk8 的时间处理姿势还不了解一下? 还看不懂同事的代码?Lambda ...
- PHP RSA签名(公钥、私钥)
签名算法: Setp.1 确定待签名参数 在请求参数列表中,除去sign参数外,其他需要使用到的参数皆是要签名的参数. 在通知返回参数列表中,除去sign参数外,凡是通知返回回来的 ...
- 基于@Scheduled注解的Spring定时任务
1.创建spring-task.xml 在xml文件中加入命名空间 <beans xmlns="http://www.springframework.org/schema/beans& ...
- nyoj 8-一种排序 (贪心)
8-一种排序 内存限制:64MB 时间限制:3000ms Special Judge: No accepted:9 submit:18 题目描述: 现在有很多长方形,每一个长方形都有一个编号,这个编号 ...
- IntelliJ IDEA使用报错
GZIPResponseStream不是抽象的, 并且未覆盖javax.servlet.ServletOutputStream中 继承了某个抽象类, 或者 实现某个接口这时候你必须 把基类或接口中的所 ...
- 京东物流出问题了?褥了30块羊毛 & 浅析系统架构
本人亲身经历,但后续的流程分析都是个人猜测的,毕竟没有实际做过这块的业务. 订单物流阻塞经过 火热的双11刚刚退去,截止今日,我在京东购买的矿泉水终于到货啦,下单两箱还只收到了一箱 :( ,从下单到收 ...