IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 集合基础-Map -> 正文阅读

[数据结构与算法]集合基础-Map

作者:more-toolbox-new

Map是一个接口,其包含了多个实现类。Map是利用键值对的方式,来存储的。Key相当于扩大了索引的内容,不再局限于数组中的数字。

?HashMap

HashMap的底层实现采用了Hash表,这是一种非常重要的数据结构。key的hashcode值用于分割其在Entry[]中的位置,并在后面存储数据。具有极快的访问速度,但是其遍历顺序却是不确定的(因为在Hashmap的散列里,我们利用的散列方法会导致其遍历顺序的变化)。HashMap最多只允许记录一条键为null的记录。同时HashMap非线程安全的。如果想满足线程安全,可以使用synchronizedMap或者ConcurrentHashMap。

??????? HashMap在Java7中的实现是利用的一个数组+链表。数组中每个元素都是一个单向链表

??????? 而HashMap为了进一步提高效率,在Java8中,引入了红黑树。

HashMap在Java8中引入了红黑树,当链表的长度大于8之后,Java就会自动将链表转换成红黑树。将此前查找的时间复杂度由O(n)下降到了O(logn)

?

下面我们实现一种最基础的数组加链表形式的Map。分别要实现其put ,get 功能,并且要保证Key的唯一性。同时,我们重写toString方法,方便我们遍历整个Map。并且使用泛型操作。

package 集合.Map.手写HashMap;

import java.util.Arrays;

/**
 * @program:多线程和IO
 * @descripton:
 * @author:ZhengCheng
 * @create:2021/10/11-19:43
 **/
public class HashMap_ <T,E>{
    private Node[] Entry ;
    private int size ;
    public HashMap_() {
        init();
    }

    private void init() {
        size = 16;
        Entry = new Node[size];
    }
    //key对应的HashCode
    private int gethashCode(T key){
        return key.hashCode();
    }
    public void put(T key,E val){
        int hash = gethashCode(key);
        int index = getPosition(hash);

        if (Entry[index] == null){
            Entry[index] = new Node(hash,key,val);
        }else {
            //遍历列表判断是否冲突
            Node check = checkHash(hash,index);
            if (check == null){
                Node temp = Entry[index];
                while (temp.next == null){
                    temp.next = new Node(hash,key,val);
                }
            }else {
                System.out.println("冲突,添加失败");
                return;
            }
        }
    }

    private Node checkHash(int hash ,int index) {
         Node temp = Entry[index];
         while (temp.next!=null && temp.getHash()!=hash){
             temp = temp.next;
         }
         if (temp.next == null && temp.getHash() !=hash){
             return null;
         }
         return temp;
    }

    private int getPosition(int hash){
        return hash&(size-1);
    }
    public E get(T key){
        int hash = gethashCode(key);
        //比较有无hash?如何快速比较呢?没有方法
        int index = getPosition(hash);
        Node temp =checkHash(hash,index);
        if (temp != null){
            E v = (E) temp.getVal();
            return v;
        }else {
            System.out.println("无");
        }
        return null;
    }
    //方便查看map里的键值对内容  遍历数组遍历链表
    @Override
    public String toString() {
        String res = "";
        for (int i = 0; i < Entry.length; i++) {
            if (Entry[i] != null){
                //遍历链表
                Node tmp = Entry[i];
                while (tmp.next != null){
                    res += tmp.toString();
                    tmp = tmp.next;
                }
                res += tmp.toString();
            }
        }
        return res;
    }
}
class Node <T,E>{
    public int hash;
    private T key;
    private E val;
    public Node next ;

    public int getHash() {
        return hash;
    }

    public void setHash(int hash) {
        this.hash = hash;
    }

    public T getKey() {
        return key;
    }

    public void setKey(T key) {
        this.key = key;
    }

    public E getVal() {
        return val;
    }

    @Override
    public String toString() {
        return "Node{" +
                "key=" + key +
                ", val=" + val +
                '}';
    }

    public void setVal(E val) {
        this.val = val;
    }

    public Node(int hash, T key, E val) {
        this.hash = hash;
        this.key = key;
        this.val = val;
    }
}
public class testDemo {
    public static void main(String[] args) {
        HashMap_<Integer, Integer> map = new HashMap_<>();
        map.put(1,23);
        map.put(1,22);
        map.put(2,1);
        map.put(3,1);
        map.put(4,1);

        Integer i = map.get(1);
        System.out.println(i);
        System.out.println(map);
    }
}

冲突,添加失败
23
Node{key=1, val=23}Node{key=2, val=1}Node{key=3, val=1}Node{key=4, val=1}

Process finished with exit code 0

TreeMap

public class TreeMap<K,V>
    extends AbstractMap<K,V>
    implements NavigableMap<K,V>, Cloneable, java.io.Serializable
private final Comparator<? super K> comparator;
private transient Entry<K,V> root;
private transient int size = 0;
private transient int modCount = 0;

TreeMap实现了SortedMap接口(实现了NavigatableMap ,NM是实现了Sorted的),能够把它保存的记录根据键的排序(默认Comparable升序或者自己使用Comparable重新排序)可以用Iterator遍历Treemap。

??????? 当我们需要排序的映射时,建议使用TreeMap。

注意:在使用TreeMap时,key必须要实现Comparable接口,或者在构造TreeMap时传入Comparator,否则会在运行中抛出ClassCastException。

后续的ConcurrentHashMap,HashTableLinkHashMap在提到了再深入了解。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-13 22:28:03  更:2021-10-13 22:28:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:24:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码