Java-04 集合框架3-Map

1. Map接口

        Map接口是Map体系的根接口,定义了键值对的容器;Map接口允许存储 无序、无下标、键不可重复,值可重复的 键值对。

        1)Map接口的实现类:

                HashMap:基于哈希表(数组+链表/红黑树)实现的键值对存储结构

                TreeMap:基于红黑树实现的键值对存储结构。

注意:Map接口未实现任何接口。

        2)Map接口的常用方法:

                V put(K key, V value)         // 将对象存入到集合中,关联键值,key重复则覆盖原值

                Object get(Object key)         // 依据键获取对应的值

                Set<K> keySet()         // 返回所有的key的Set

                Collection<V> values()          // 返回包含所有value的Collection集合

                Set<Map.Entry<K,V>>  entrySet         // 返回所有键值对key-value的Set集合

        3)Map接口的遍历方式:

                Map虽然没有实现Iterable接口,但其中提供了forEach循环。

                · 通过keySet()方法遍历;

                · 通过entrySet()方法遍历;

public class Test{
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        
        // 添加元素
        map.put("张三",23);
        map.put("李四",24);
        map.put("王五",25);
        
        // 遍历
        // keySet()遍历
        for (String k:map.keySet()) {
            System.out.println(k + map.get(k));
        }
        // entrySet()遍历
        for (Map.Entry<String,Integer> entry: map.entrySet()) {
            System.out.println(entry.getKey()+entry.getValue());
        }
    }
}

       

1.1 实现类HashMap         

         1)概述:

                基于哈希表的Map集合,运行效率较快,但线程不安全。HashMap的查询、添加、删除操作的时间复杂为O(1),其底层通过数组+链表/红黑树的方式实现。允许用null 作为key 或 value。其无参构造器默认构造一个初始容量为16,默认扩容因子0.75的空HashMap。

                key 与 value 的对应关系:在HashMap中key与value为一对一映射关系,Map接口不允许出现key重复,但允许value重复,因此一个key只能对应一个value,但一个value可以对应多个key。

                key-value的存储

                        · hashcode:通过HashMap中的hashCode()方法计算出的值(Java官方直接调用Object中的Native方法hashCode()计算); 

// HashMap中Node的计算方式
public final int hashCode() {
    return Objects.hashCode(key) ^ Objects.hashCode(value);
}

                        · hash:基于hashCode经过一定方法计算而成的;

// Java官方的hash计算方式

static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

可以看出:

        当 key 为空的时候,hash = 0;否则 hash 为 key的hashcode 与自身右移16位的结果进行异或运算。

                        · index(数组索引):Java官方通过位运算&计算 length-1 与 hash值得到的(相较于取模速度更快)。

                对于一对key-value键值对,首先通过key计算其数组索引index,该index上没有key-value键值对则直接赋值。如果有,判断两个键值对基于key计算的hashcode是否相同,相同则用新的键值对覆盖原键值对,否则将新键值对以链表元素的方式添加进数组中

        2)HashMap的遍历

                相比较于Map,HashMap在其子类KeySetEntrySet中均实现了迭代器,可以通过迭代器遍历HashMap中的对象。也可以通过keySet()、entrySet()方法通过foreach循环遍历

// 通过键集合keySet遍历HashMap(forEach循环)
// 假设key的类型为char

for( char k:map.keySet()){
    System.out.println(map.get(k));
}

        3)HashMap源码分析:

                 · static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;     //  初始容量16

                 · static final float DEFAULT_LOAD_FACTOR = 0.75f;        // 扩容因子0.75

                 当链表长度大于8,且散列表中的元素个数>64,将链表转换为红黑树;当中元素个数<6时,红黑树退化为链表。

HashMap中的地址碰撞:

        解决方法:链地址法(链表),加入红黑树是为了在元素过多的时候提高查询效率。

               核心:理解HashMap的存储、查询、添加与删除。

                · V put(K key, V value)方法:

                        在HashMap的构造方法中并不会创建数组,而是在首次添加(put)时创建。对于put方法,首先通过传入的key计算索引index,判断该位置上是否有元素,没有则添加;有,并且key算出的hashcode相同,覆盖;有,但是key算出的hashcode不相同,添加到链中。

                         如果 key 为null,添加到 index = 0位置 或 index = 0的冲突链上。

                · V get(K key, V value)方法:

                        对于put方法,首先通过传入的key计算索引index,判断该位置上是否有元素,没有则返回null;有元素则遍历该index上的链表,通过key的equals方法判断是否相等,返回相等的元素。

         4)HashTable:

                线程安全,运行效率慢,不允许null作为key或者是value。

                Properties是HashTable的子类,要求key和value都是String,通常用于配置文件的读取。

1.2 实现类TreeMap

        1)概述:

                实现了SortedMap接口(Map的子接口),可以对key自动排序,要求传入Comparator用于比较entry的大小。底层存储结构为红黑树

        2)TreeMap的遍历:

                TreeMap只能通过keySet()、entrySet()进行遍历。

2. Collections工具类

        1)概述:

                java中的工具类(实现类),类名为java.util.Conllections,定义了除了存取以外的集合的常用方法(主要是static方法与在collection对象上操作的方法)。

        2)常用方法:

                public static void reverse(List<?> list)         // 反转集合中的元素的顺序

                public static void shuffle(List<?> list)        // 随机重置集合元素的顺序

                public static void sort(List<T> list)       // 升序排序(元素类型必须实现Comparable接口 )

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值