My集合框架第四弹 HashTable(链表解决冲突)

package com.wpr.collection;

import java.util.LinkedList;
import java.util.List;

public class HashTable<AnyType> {

    private static final int DEFAULT_TABLE_SIZE = 101;

    private List<AnyType>[] theList;
    private int curSize;

    public HashTable() {
        this(DEFAULT_TABLE_SIZE);
    }

    public HashTable(int size) {
        //构造一个质数长度的链表
        this.theList = new LinkedList[nextPrime(size)];
        for(int i=0;i<theList.length;i++){
            theList[i]= new LinkedList<>();
        }
    }
    /**
     * 插入,如果元素已经存在,直接返回
     * @param x
     */
    public void insert(AnyType x){
        List<AnyType> temp = theList[myHast(x)];
        if(!temp.contains(x)){
            temp.add(x);
            if(++curSize>theList.length)
                reHash();
        }
    }
    /**
     * 表的size太小,数据的长度和表长相等时重新调整表长,装填因子为1
     */
    private void reHash() {
        List<AnyType>[] old = theList;
        theList = new LinkedList[theList.length*2];
        //更新hashTable
        for(int i=0;i<theList.length;i++)
            theList[i]=new LinkedList<>();
        curSize = 0;

        for(int i=0;i<old.length;i++){
            for(AnyType x:old[i])
                insert(x);
        }
    }

    public void clear(){
        for(List l:theList){
            l.clear();
        }
    }
    public void remove(AnyType x){
        List<AnyType> temp = theList[myHast(x)];
        if(temp.contains(x)){
            temp.remove(x);
            curSize--;
        }
    }
    public boolean contain(AnyType x){
        List<AnyType> temp = theList[myHast(x)];
        return temp.contains(x);
    }
    /**
     * 计算数据的hash值
     * @param x
     * @return
     */
    private int myHast(AnyType x) {
        int hashValue = x.hashCode();

        hashValue%=theList.length;
        if(hashValue<0)
            hashValue+=theList.length;
        return hashValue;
    }

    /**
     * 返回一个比size大的质数
     * @param size
     * @return
     */
    private int nextPrime(int size) {
        if(size%2==0)
            size++;
        while(!isPrime(size)){
            size +=2;
        }
        return 0;
    }
    /**
     * 判断size是否为质数
     * @param size
     * @return
     */
    private boolean isPrime(int size) {
        if(size%2==0||size==1)
            return false;
        if(size==2 || size==3)
            return true;
        for(int i=3;i<Math.sqrt(size);i+=2){
            if(size%i==0)
                return false;
        }
        return true;
    }
}
时间: 2024-10-08 18:34:19

My集合框架第四弹 HashTable(链表解决冲突)的相关文章

Java集合框架(四)_day18

18.集合框架(Map集合概述和特点) A:Map接口概述 查看API可以知道: 将键映射到值的对象 一个映射不能包含重复的键 每个键最多只能映射到一个值 B:Map接口和Collection接口的不同 Map是双列的,Collection是单列的 Map的键唯一,Collection的子体系Set是唯一的 Map集合的数据结构值针对键有效,跟值无关;Collection集合的数据结构是针对元素有效 18.集合框架(Map集合的功能概述) A:Map集合的功能概述 a:添加功能 V put(K

Java 集合框架(四)—— HashMap

原文出处:Java8 系列之重新认识 HashMap 摘要 HashMap 是 Java 程序员使用频率最高的用于映射 (键值对) 处理的数据类型.随着 JDK(Java Developmet Kit)版本的更新,JDK1.8 对 HashMap 底层的实现进行了优化,例如引入红黑树的数据结构和扩容的优化等.本文结合 JDK1.7 和 JDK1.8 的区别,深入探讨 HashMap 的结构实现和功能原理. 简介 Java 为数据结构中的映射定义了一个接口 java.util.Map,此接口主要有

java 集合框架(十四)Queue

一.概述 Queue一种队列结构集合,用来存储将要进行处理的元素.通常以FIFO的方式排序元素,但这并不是必须的.比如优先度队列就是一个例外,它是以元素的值来排序.但无论怎样,每个Queue的实现都必须指定它的排序属性.Queue通常不定义元素的equal和hashCode方法. 二.主要方法 每个Queue方法都存在两种形式(1)操作失败则抛出异常(2)操作失败返回一个特定值,通常是null或者是false 操作类型 抛出异常 返回特定值 Insert add(e) offer(e) Remo

java集合框架12——HashMap和HashTable的区别

前面已经学习了Map的部分内容,主要是HashMap和HashTable,这一节我们来看看它们两有啥异同点. 1. HashMap和HashTable的相同点 HashMap和HashTable都是存储"键值对"的散列表,而且都是采用拉链法来实现的.存储的思想都是:通过table数组存储,数组的每个元素都是一个Entry,而一个Entry就是一个单项链表,Entry链表中的每个节点都保存了key-value数据. HashMap和HashTable的相同点基本没啥好研究的,我们更多的是

JAVA学习第三十六课(常用对象API)- 集合框架(四)— Set集合:HashSet集合演示

随着Java学习的深入,感觉大一时搞了一年的ACM,简直是明智之举,Java里很多数据结构.算法类的东西,理解起来就轻松多了 Set集合下有两大子类开发常用 HashSet集合 .TreeSet集合 Set集合的元素是不重复且无序 一.HashSet集合 API文档解释:此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持.它不保证 set 的迭代顺序:特别是它不保证该顺序恒久不变.此类允许使用null 元素. 此类为基本操作提供了稳定性能,注意,此实现不是同步的. 由上可

My集合框架第三弹 AVL树

旋转操作: 由于任意一个结点最多只有两个儿子,所以当高度不平衡时,只可能是以下四种情况造成的: 1. 对该结点的左儿子的左子树进行了一次插入. 2. 对该结点的左儿子的右子树进行了一次插入. 3. 对该结点的右儿子的左子树进行了一次插入. 4. 对该结点的右儿子的右子树进行了一次插入. 向AVL树插入节点后,需要让AVL树重新平衡 step1:从插入节点向根节点溯源,观察是否存在不平衡节点(左右子树高度差),    if(不存在),return    else  step2step2:标记不平衡

jdk源码阅读笔记之java集合框架(四)(LinkedList)

关于LinkedList的分析,会从且仅从其添加(add)方法入手. 因为上一篇已经分析过ArrayList,相似的地方就不再叙述,关注点在LinkedList的特点. 属性: /** *链表头 */ transient Node<E> first; /** * 链表尾 */ transient Node<E> last; 从以上两个属性可以得出LinkedList是基于双向链表实现的. 节点代码(无需过多解释): private static class Node<E>

黑马程序员-----集合框架类(四) 高级for循环、方法的可变参数及静态导入

1.1 高级for循环(示例1) 格式:for(数据类型 变量名 : 被遍历的集合(Collection)或者数组){ } 对集合进行遍历.只能获取集合元素.但是不能对集合进行操作. 迭代器除了遍历,还可以进行remove集合中元素的动作.如果是用ListIterator,还可以在遍历过程中对集合进行增删改查的动作. 1.1.2 传统for和高级for有什么区别呢? 高级for有一个局限性.必须有被遍历的目标. 1 示例1: 2 import java.util.*; 3 4 class For

My集合框架第五弹 最小堆

二叉堆(以最小堆为例),其具有结构性质和堆序性质结构性质: 堆是一棵完全的二叉树,一颗高为h的完全二叉树有2^h到2^h-1个节点,高度为log N            而且该结构可以很容易的使用数组来表示:对于数组中任一位置i上的元素,其左儿子在位置2i上,右儿子在2i+1,其父节点在[x/2]处堆序性质:在一个堆中,对于每一个节点X,X的父亲中的关键字小于或等于X中的关键字          也就是说:最小元总可以在根处找到 主要的操作为插入和删除: 以数组存储为例,算法在代码中体现: /