文档章节

Map 基础知识整理

宇哥v587
 宇哥v587
发布于 2017/05/18 20:23
字数 1149
阅读 4
收藏 1

 

Map(接口):
    与 Collection 并列存在。用于保存具有映射关系的数据:Key-Value。

    Key 于 Value 可以是任何引用类型的数据。
    其中 K 不允许重复
    Map 对象所对应的类,须重写 hashCode() 和 equals() 方法。
    key 和 value 之间总存在单向一对一关系,即通过指定的 key 总能找到唯一的,确定的值。
    
    因为 K 是唯一的,所以 keySet() 返回的是一个 Set.
    而 values() 返回的是一个  Collection。

    一个 K-V 对,是一个 Entry。 所有的 Entry 是用 Set 存放的,也是不可重复的

 

Map接口继承树:

 

如果右侧 Value 全为 null,看起来不就是一个 HashSet。

下为 HashSet 构造方法

private transient HashMap<E,Object> map;

 public HashSet() {
    map = new HashMap<E,Object>();
    }

说明 HashMap  与 HshSet 底层是有关系的。

 

Map常用方法

1、map.put( null,null );//可以传一个 null 键和多个 null 值。

2、HashMap 重写了 equals 方法,所以

        map.put( new Person("SS"), 83); 

        会被 map.put( new Person("SS"), 87);  覆盖。

 

实例练习:

1、@Test
    public void map1(){
        Random rand = new Random(47);
        Map<Integer, Integer> m = new HashMap<Integer,Integer>();
        for(int i=0;i<10000; i++){
            int key = rand.nextInt(20);//生成一个[0,20)之间的随机数
            Integer freq = m.get(key);
            m.put(key, freq==null ? 1 : freq+1);//If the map 以前包含一个该键的映射关系, 则用指定值替换旧值;
                                                //由此得出 每个 key 生成了多少次
        }
        System.out.println(m);
    }

 

2、public class MapOfList{
    
    public static Map<Person, List<? extends Pet>> petPeople
                                                                = new HashMap<Person, List<? extends Pet>();
    static {
        petPeople.put(new Person("Dawn"), Arrays.asList(new Cymric("Molly"), new Mutt("Spot")));
        petPeople.put(new Person("Dawn"), Arrays.asList(new Cymric("K"), new Mutt("S")));
    }
    public static void main(String[] args){
        //第一种:获取 K-V 的方法(先竖着获取所有 K,再通过 K 单向映射到 V)
        for(Person person :petPeople.keySet() ){
            System.out.printIn(person);
            for(Pet pet: petPeople.get(person)){
            System.out.printIn(pet);
        }
        
        //第二种:获取 K-V 的方法(先横着获取 K-V 对,再遍历每个 K-V 对的 K , V)
        for(Map.Entry<Person, List<? extends Pet>> m: petPeople.entrySet()){
                    String key=m.getKey();
                    Object value=m.getValue();
        }
        }
    }

 

Map 中的内部 接口

interface Entry<K, V>{
        K getKey();
        V getValue();
        V setValue(V value);
        boolean equals(Object o);
        int hashCode();
    }

被 HashMap 中的内部类继承

 static class Entry<K,V> implements Map.Entry<K,V> {
        final K key;
        V value;
        Entry<K,V> next;
        int hash;


        Entry(int h, K k, V v, Entry<K,V> n) {
            value = v;
            next = n;
            key = k;
            hash = h;
        }

        public final K getKey() {
            return key;
        }

        public final V getValue() {
            return value;
        }

        public final V setValue(V newValue) {
            V oldValue = value;
            value = newValue;
            return oldValue;
        }

        public final boolean equals(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry e = (Map.Entry)o;
            Object k1 = getKey();
            Object k2 = e.getKey();
            if (k1 == k2 || (k1 != null && k1.equals(k2))) {
                Object v1 = getValue();
                Object v2 = e.getValue();
                if (v1 == v2 || (v1 != null && v1.equals(v2)))
                    return true;
            }
            return false;
        }

        public final int hashCode() {
            return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue());
        }

        public final String toString() {
            return getKey() + "=" + getValue();
        }
        void recordAccess(HashMap<K,V> m) {
        }
        void recordRemoval(HashMap<K,V> m) {
        }
    }

结论:可以看出其中的 hashCode() , equals(Object o), toString()  都被重写。

 

LinkedHashMap:

    类比:LinkedHashSet

    使用链表维护添加进 Map 中的顺序。故遍历 Map 时按添加的顺序遍历

 

TreeMap:

类比: TreeSet

按照添加进 Map 中的元素的 key 的指定属性进行排序。Key 必须是同一个类对象。

TreeMap 中的 V 全部为 null 时,相当于一个 TreeSet.

 

自然排序 和 定制排序。

自然排序,要求: Person implements Comparable

@Override
public int compareTo(Object o){
    if(o instanceof Person){
        Person p =(Person)o;
        int i = this.age.compareTo(p.age);
        if(i == 0){
            return this.name.compare(p.name);
        }else{
        return 1;
        }
    }
    return 0;
}

定制排序
public void test1(){
    //实现匿名内部类
    Comparator com = new Comparator(){
        public int compareTo(Object o1, Object o2){
            if(o1 instanceof Customer && o2 instanceof Customer){
                Customer c1 = (Customer) o1;
                Customer c2 = (Customer) o2;
                int i = c1.getId().compareTo(c2.getId());
                if(i == 0){
                    return c1.getName().compareTo(c2.getName());
                }
                return i;
            }
            return 0;
        }
    };
    
    TreeMap map = new TreeMap(com);
    map.put(new Customer("AA", 1001),87);
    map.put(new Customer("CC", 1001),87);
    map.put(new Customer("AA", 1002),87);
    map.put(new Customer("BB", 1001),87);
}

小结:

自然排序:TreeMap 的所有的 Key 必须实现 Comparable 接口,而且所有的 Key 应该是同一个类的对象,否则将会抛出 ClasssCastException

定制排序:创建 TreeMap 时,传入一个 Comparator 对象,该对象负责对 TreeMap 中的所有 key 进行排序。此时不需要 Map Key 实现 Comparable 接口

 

HashMap & Hashtable

HashMap Hashtable Map 接口的两个典型实现类

区别:

Hashtable 是一个古老的 Map 实现类,不建议使用

Hashtable 是一个线程安全的 Map 实现,但 HashMap 是线程不安全的。

Hashtable 不允许使用 null 作为 key value,而 HashMap 可以

HashSet 集合不能保证元素的顺序的顺序一样,Hashtable 、HashMap 也不能保证其中 key-value 对的顺序

Hashtable HashMap 判断两个 Key 相等的标准是:两个 Key 通过 equals 方法返回 truehashCode 值也相等。

Hashtable HashMap 判断两个 Value相等的标准是:两个 Value 通过 equals 方法返回 true。

 

Prpperties:

Hashtable 的子类。

常用来处理属性文件,键值都为 String  类型的

 

 

 

 

 

 

 

© 著作权归作者所有

共有 人打赏支持
宇哥v587
粉丝 1
博文 47
码字总数 20855
作品 0
南京
程序员
2017 我的技术之路:不忘初心,夯实基础

2017 我的技术之路:不忘初心,夯实基础 又一年春去冬来,到了年末盘点的时候,感觉自己今年相较于前两年沉稳了些,也愈能明晰自身的不足;所以本年的主题就定为了不忘初心,夯实基础。今年年...

2017/12/27
0
0
Web开发系列 - GIS

Google Maps JQuery Maps google map是怎样工作的 Google Maps API编程资源大全 google map限制地图缩放级别和显示范围 WebGIS近来学习小结,GoogleMap影像在线矢量化简述 google map v3 ap...

长征2号
2017/08/09
0
0
Rxjava 2.x 源码系列 - 变换操作符 Map(上)

Rxjava 2.x 源码系列 - 基础框架分析 Rxjava 2.x 源码系列 - 线程切换 (上) Rxjava 2.x 源码系列 - 线程切换 (下) Rxjava 2.x 源码系列 - 变换操作符 Map(上) 前言 在前几篇博客中,我...

xujun9411
06/26
0
0
Linux学习笔记:基础知识学习整理【图】

原本课程中还有最后一部分shell基础的讲解,我没有整理出来。我觉着下一次整理shell知识时再整理比较好。嗯,真实原因是我累了,三点开始整理到现在不想搞了。 源文件也在里面,需要的自己添...

countryman
2016/03/20
118
0
程序员必备,快速学习 Python 的全套14张思维导图(附高清版下载)

后台回复关键词 思维导图 可获取本文中的高清思维导图(PDF版) ML & AI∣一个有用的公众号 长按,识别二维码,加关注 获取更多精彩文章

micf435p6d221ssdld2
05/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

[雪峰磁针石博客]软件测试专家工具包1web测试

web测试 本章主要涉及功能测试、自动化测试(参考: 软件自动化测试初学者忠告) 、接口测试(参考:10分钟学会API测试)、跨浏览器测试、可访问性测试和可用性测试的测试工具列表。 安全测试工具...

python测试开发人工智能安全
今天
2
0
JS:异步 - 面试惨案

为什么会写这篇文章,很明显不符合我的性格的东西,原因是前段时间参与了一个面试,对于很多程序员来说,面试时候多么的鸦雀无声,事后心里就有多么的千军万马。去掉最开始毕业干了一年的Jav...

xmqywx
今天
2
0
Win10 64位系统,PHP 扩展 curl插件

执行:1. 拷贝php安装目录下,libeay32.dll、ssleay32.dll 、 libssh2.dll 到 C:\windows\system32 目录。2. 拷贝php/ext目录下, php_curl.dll 到 C:\windows\system32 目录; 3. p...

放飞E梦想O
今天
0
0
谈谈神秘的ES6——(五)解构赋值【对象篇】

上一节课我们了解了有关数组的解构赋值相关内容,这节课,我们接着,来讲讲对象的解构赋值。 解构不仅可以用于数组,还可以用于对象。 let { foo, bar } = { foo: "aaa", bar: "bbb" };fo...

JandenMa
今天
1
0
OSChina 周一乱弹 —— 有人要给本汪介绍妹子啦

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子 :分享水木年华的单曲《中学时代》@小小编辑 手机党少年们想听歌,请使劲儿戳(这里) @须臾时光:夏天还在做最后的挣扎,但是晚上...

小小编辑
今天
68
8

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部