Java集合-Map

Map接口

        Map是一种映射表,可以通过key快速查找value;Map接口用于表示键值对的集合, Map集合中的key键是唯一的,而value值可以重复。

public class Main {
    public static void main(String[] args) {
        Student s = new Student("Xiao Ming", 99);
        
        Map<String, Student> map = new HashMap<>();
        map.put("Xiao Ming", s); // 将"Xiao Ming"和Student实例映射并关联
        
        Student target = map.get("Xiao Ming"); // 通过key查找并返回映射的Student实例
        
        System.out.println(target == s); // true,同一个实例
        System.out.println(target.score); // 99
        
        Student another = map.get("Bob"); // 通过另一个key查找
        System.out.println(another); // 未找到返回null
    }
}

class Student {
    public String name;
    public int score;
    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
}

Map的主要实现类包括:

HashMap :基于哈希表实现,提供快速的查找和插入性能;

LinkedHashMap: HashMap 类的子类,内部多维护了一条双向链表,保存维护了元素的插入顺序;

TreeMap :基于红黑树实现,根据 key 键自动排序或按照自定义规则排序;

Hashtable :基于哈希表实现,key 和 value 不允许为 null。早期的线程安全实现类,使用 synchronize

ConcurrentHashMap :基于哈希表实现,使用 synchronized +CAS 实现线程安全;

HashMap的数据结构

HashMap的数据结构采用数组(哈希表)+链表+红黑树

1.数组(哈希表):

Hashmap 内部定义了一个数组,数组中的每个位置被称为“桶”(Bucket ),这是 Hashmap 的基础结构【哈希表】;

下标位置:当添加一个新的 key-value 键值对时,会根据 key 的 hashcode(),通过哈希函数计算出一个新的哈希值 hash ,并通过这个 hash 值,计算 key-value 键值对在数组中的下标位置(桶Bucket);

数组容量:在添加第一个 key-value 键值对时,数组容量被初始化为 16,并且可以根据 key-value 键值对的数量和负载因子,数组会自动按照 2倍进行扩容;

2.链表:
数组的每个位置( Bucket 桶)可以保存一个或多个 key-value 键值对;

当两个或更多的 key-value 键值对,被映射保存到数组的同一个位置(桶 Bucket )时,就产生了哈希表冲突;

Hashmap 使用链地址法,解决哈希冲突,这些键值对将以链表的形式存储在产生冲突的位置(桶Bucket);

3.红黑树:
为了优化链表的査询性能,当链表长度超过一个阈值(默认是 8)并且数组的容量大于等于 64 时,链表会转换成红黑树,

        红黑树是一种自平衡的二叉查找树,它可以基于二分查找的方式,进行元素的查找,提高查找搜索性能,这对于较长的链表来说是一个明显的性能提升;

        当红黑树中的节点数量减少到 6个或更少时,红黑树将转换回链表;

HashMap为什么使用链表

        Hashmap 使用哈希表作为基础数据结构,当两个不同的 key-value 键值对,通过 hash 哈希值计算数组下标,出现相同下标情况时,产生哈希冲突;
        Hashmap 使用“链地址法”解决哈希冲突,所以需要使用链表,来保存产生哈希冲突的 key-value 键值对;

HashMap为什么使用红黑树

        Hashmap 中的链表长度增长到一定长度,会导致搜索性能下降;(链表是线性方式搜索)          

        所以, Hashmap 会在链表过长时,将链表转换为红黑树,通过红黑树提供搜索性能;(红黑树是二分查找方式搜索)

        Hashmap 不直接用红黑树的原因是:链表简单易于维护,红黑树维护复杂。所以首选使用链表,只有链表长度过长时,才会转换成红黑树来提高搜索查找的性能;

HashMap的遍历方式

//使用 entrySet()和for-each 循环
for (Map.Entry<string,Integer>entry :map.entryset()){
    System.out.println("Key ="+ entry.getKey()+",Value = "+ entry.getValue());
}
//使用keySet()和value()
for(String key:map.keySet()){
    System.out.println("Key="+ key);
}
for(Integer value :map.values()){
    System.out.println("Value ="+ value);
}

 

HashMap、LinkedHashMap 、TreeMap的区别

HashMap:无序,基于数据+链表+红黑树;

LinkedHashMap:有序,HashMap的子类;

TreeMap:自动排序,按照key或自定义Comparator比较器,进行排序;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值