`

java_集合体系之Map体系总结(一)

阅读更多

1、Map概述

1.1 什么是Map

Map是将键映射到值( key-value )的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。Map 接口提供三种collection 视图,允许以键集(keySet())、值集(values())或键-值映射关系集(entrySet())的形式查看某个映射的内容( 即获取键值对的内容 )。

映射顺序定义为迭代器在映射的 collection 视图上返回其元素的顺序,即可以映射得到键、值和键-值的Set集合,元素的顺序是由得到的Set集合所决定的。某些映射实现可明确保证其顺序,如 TreeMap 类;另一些映射实现则不保证顺序,如 HashMap 类 。

1.11、Map接口

Map<K,V>,一次添加一对元素(又称键值对)。K是键,V是值。而Collection一次添加一个元素。Map集合也称为双列集合,Collection集合也称为单列集合。其实Map集合中存储的就是键值对,且保证键(K)的唯一性。

Map常用的子类:

1、Hashtable:内部结构是哈希表,是同步的。不支持null作为键和值。

2、HashMap:内部结构是哈希表,不是同步的,支持null作为键和值。

3、TreeMap:内部结构是二叉树,不是同步的,支持null作为键和值。

Map接口常用的方法如下:

1、添加

value put(key,value);//返回前一个与key关联的值,如果没有则返回null

2、删除

value  remove(key);//根据指定的key删除这个键值对
void clear();//清除这个Map集合

3、判断

boolean  containsKey(key);
boolean  containsValue(value);
boolean  isEmpty();//判断是否为空

4、获取

value get(key);//用过键来返回值,如果没值该键返回null。当然可以通过返回null来判断是否包含指定的键(K) 
int size();//获取键值对的个数

1.12、Map接口是如何实例化的,如何遍历元素的??

这里演示一个HashMap实例化的例子:

Map<Integer,String> map=new HashMap<Integer,String>();//实例化一个HashMap对象

注意:问题:如何获取map中的所有的元素???

取出map中的元素,原理如下:通过keySet方法获取map中所有键所在的Set集合中,再通过Set的迭代器获取到每个键。然后对每个键通过map集合的get()方法获取其所对应的值。

1.2 Map与Collection的区别

  • 1.Map 存储的是键值对形式的元素,键唯一,值可以重复。
  • 2.Collection 存储的是单列元素,子接口Set元素唯一,子接口List元素可重复。
  • 3.Map集合的数据结构值针对键有效,跟值无关,Collection集合的数据结构是针对元素有效

关于Collection可以戳这里java集合框架之Collection实例解析

2、Map继承体系

下面列出了常见Map集合的继承体系与他们的特点

---Map 键唯一
    |------HashMap
    基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。 此实现不是同步的。
        |------LinkedHashMap
    Map接口的哈希表和链接列表实现,具有可预知的迭代顺序。此实现与 HashMap 的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序通常就是将键插入到映射中的顺序(插入顺序)。此实现不是同步的
    |------WeakHashMap
    以弱键 实现的基于哈希表的 Map。在 WeakHashMap 中,当某个键不再正常使用时,将自动移除其条目。更精确地说,对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,然后被回收。丢弃某个键时,其条目从映射中有效地移除,null 值和 null 键都被支持。
    |------Hashtable
    此类实现一个哈希表,该哈希表将键映射到相应的值。任何非 null 对象都可以用作键或值。        Hashtable 是同步的 

    |------TreeMap
    基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。 此实现不是同步的

3、Map泛型接口

Map特点 : 由key-value键值对组成,键不可重复,值可重复

大致包含如下功能:

  • 插入(put、putAll())、删除(remove())
  • 获取(entrySet()、get()、keySet()、size()、values())
  • 判断(containsKey()、containsValue()、equals()、isEmpty())、清除(clear())
  • 替换(replace(),replace(K key, V oldValue, V newValue) jdk1.8之后,后面示例会讲到它们)

  • void clear() 
              从此映射中移除所有映射关系(可选操作)。 
     boolean containsKey(Object key) 
              如果此映射包含指定键的映射关系,则返回 trueboolean containsValue(Object value) 
              如果此映射将一个或多个键映射到指定值,则返回 trueSet<Map.Entry<K,V>> entrySet() 
              返回此映射中包含的映射关系的 Set 视图。 
     boolean equals(Object o) 
              比较指定的对象与此映射是否相等。 
     V get(Object key) 
              返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。 
     int hashCode() 
              返回此映射的哈希码值。 
     boolean isEmpty() 
              如果此映射未包含键-值映射关系,则返回 trueSet<K> keySet() 
              返回此映射中包含的键的 Set 视图。 
     V put(K key, V value) 
              将指定的值与此映射中的指定键关联(可选操作)。 
     void putAll(Map<? extends K,? extends V> m) 
              从指定映射中将所有映射关系复制到此映射中(可选操作)。 
     V remove(Object key) 
              如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。 
     int size() 
              返回此映射中的键-值映射关系数。 
     Collection<V> values() 
              返回此映射中包含的值的 Collection 视图。
  • 3.1、 Map集合遍历的常见方式

    方式1、根据键获取值(key -> value)

    1.获取所有键的集合
    2.遍历键的集合,获取到每一个键
    3.根据键找值
    

    方式2、根据键值对对象获取键和值( entrySet -> key,value)

    1.获取所有键值对对象的集合
    2.遍历键值对对象的集合,获取到每一个键值对对象
    3.根据键值对对象找键和值
    
  • 3.11 Map使用示例

    public class MapReview {
        public static void main(String[] args) {
            Map<String, String> map=new HashMap<String, String>();
            map.put("000", "qqq");
            map.put("003", "rrr");
            map.put("001", "www");
            map.put("002", "eee");
            map.put("004", "sss");
    
            // System.out.println(map);  // 直接打印输出键值对
    
            // 遍历1 : 通过键值对对象entrySet获取键与值
            Set<Entry<String, String>> entrySet = map.entrySet();
            for (Entry<String, String> entry : entrySet) {
                String key = entry.getKey();
                String value = entry.getValue();
                System.out.println("key="+key+" value="+value);
            }
            System.out.println("-------------------");
    
            // 遍历2 : 通过键keySet获取值
            Set<String> keySet = map.keySet(); // 得到键的集合
            for (String key : keySet) {
                String value = map.get(key);
                System.out.println("key="+key+" value="+value);
            }
            System.out.println("-------------------");
    
            // 获取Map值的集合
            Collection<String> values = map.values();
            System.out.println(values);
    
            // 判断是否存在键和值
            System.out.println("containsKey="+map.containsKey("001"));
            System.out.println("containsKey="+map.containsValue("eee"));
    
            // 向Map集合添加元素时,若键存在,则返回之前与键对应的值
            String put = map.put("000", "aaa");
            System.out.println("put="+put); // output: qqq
    
            //  default V replace(K key, V value)
            //  替换功能,将旧值替换成新值,并返回旧值(若有的话)
            String replace = map.replace("003", "666");
            System.out.println("replace="+replace);
            System.out.println(map);
    
            // default boolean replace(K key, V oldValue, V newValue
            // 只有当键key存在,并且oldValue与newValue相等时,旧的值才会被替换成新的值,并且返回true
            boolean success = map.replace("004", "sss", "lll"); 
            System.out.println("replace2="+success); // output : true
        }
    }
  • 3.2、 HashMap

    3.21.HashMap的特点

    ①键是哈希表结构,可以保证键的唯一性,
    ②当向已存在key的Map中添加元素时,会覆盖掉旧值,并将旧值返回。
    ③它允许使用 null 值和 null 键,但不保证映射的顺序,特别是它不保证该顺序恒久不变(即不会保证存储的顺序与输出的顺序恒久不变)。 
    ④此实现不是同步的。
    

    注意

    对于自定义对象,需重写其equals和hashCode方法才能保证其key的唯一性

    3.22.HashMap与Hashtable的异同

    除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同
    

    3.23.HashMap的使用示例

    public class HashMapReview {
        public static void main(String[] args) {
            test1();
            test2();
    
        }
    
        /**
         * 自定义类型做key,
         * 需重写其equals和hashCode方法才能保证其key的唯一性
         */
        private static void test2() {
            HashMap<Info, String> map=new HashMap<Info, String>();
            map.put(new Info(0, "aaa"),"0000");
            map.put(new Info(1, "bbb"),"1111");
            map.put(new Info(3, "ddd"),"3333");
            map.put(new Info(0, "aaa"),"4444");
            map.put(new Info(2, "ccc"),"2222");
            printMap(map);
            // output:
    //      key=Info [id=3, adress=ddd] value=3333
    //      key=Info [id=2, adress=ccc] value=2222
    //      key=Info [id=0, adress=aaa] value=0000
    //      key=Info [id=1, adress=bbb] value=1111
    //      key=Info [id=0, adress=aaa] value=4444  // 当Info没有重写equals和hashCode方法时,key出现重复元素
        }
    
        /**
         * String或基本数据类型的包装类做key,他们已重写了hashCode与equals方法
         * 键唯一,重复添加会替换旧值成新值
         */
        private static void test1() {
            HashMap<String, String> map=new HashMap<String, String>();
            map.put("aaa", "123");
            map.put("bbb", "789");
            map.put("aaa", "456");
            map.put("ccc", "321");
            System.out.println(map);
            // output:
    //      {aaa=456, ccc=321, bbb=789}
            // 重复的键不会重新插入,只会替换旧值成新值
        }
    
        private static void printMap(Map<Info, String> map) {
            Set<Entry<Info, String>> entrySet = map.entrySet();
            for (Entry<Info, String> entry : entrySet) {
                System.out.println("key="+entry.getKey()+" value="+entry.getValue());
            }
        }
    }
  • 3.24 一个HashMap面试题

    需求如下:

     已知一个HashMap<Integer,Person>集合, Person有name(String)和age(int)属性。
     请写一个方法实现对HashMap的排序功能。该方法接收HashMap<Integer,Person>为形参,返回类型为HashMap<Integer,Person>,要求对HashMap中的Person的age升序进行排序。排序时key=value键值对不得拆散。
    • 1
    • 2

    分析:

    HashMap本身是不保证元素的顺序不变的,要对其排序可使用LinkedHashMap,它是有序的并且还是HashMap的子类,我们可以使用它来完成排序的目的。最后返回它的实例即可满足要求 并且还符合多态的编程思想 
    

    示例代码

    public class SortedHashMapDemo {
        public static void main(String[] args) {
            HashMap<Integer, Person> map = new LinkedHashMap<Integer, Person>();
            map.put(0, new Person("小明", 20));
            map.put(1, new Person("小二", 26));
            map.put(2, new Person("小四", 19));
            map.put(3, new Person("阿七", 33));
            map.put(4, new Person("十四", 25));
            map.put(4, new Person("小花", 19));
            System.out.println(map);
            HashMap<Integer, Person> sortedHashMap = SortedHashMap(map);
            System.out.println(sortedHashMap);
        }
    
        public static HashMap<Integer, Person> SortedHashMap(
                HashMap<Integer, Person> map) {
            // 获得键值对Set集合
            Set<Entry<Integer, Person>> entrySet = map.entrySet();
            // 将键值对Set集合转化为List以用Collections来排序
            List<Entry<Integer, Person>> list = new ArrayList<Map.Entry<Integer, Person>>(
                    entrySet);
            // 通过Collections来排序,添加比较器,比较年龄
            Collections.sort(list, new Comparator<Entry<Integer, Person>>() {
                @Override
                public int compare(Entry<Integer, Person> o1, Entry<Integer, Person> o2) {
                    int result = o2.getValue().age - o1.getValue().age;
                    result = result == 0 ? o2.hashCode() - o1.hashCode() : result;
                    return result;
                }
            });
    
            // 创建LinkedHashMap来存储排好序的List元素
            LinkedHashMap<Integer, Person> linkedHashMap = new LinkedHashMap<Integer, Person>();
            // 遍历List,将元素添加到linkedHashMap中
            for (Entry<Integer, Person> entry : list) {
                linkedHashMap.put(entry.getKey(), entry.getValue());
            }
    
            return linkedHashMap;
        }
    }
    
    class Person {
        String name;
        int age;
    
        public Person(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Person [name=" + name + ", age=" + age + "]";
        }
    }
分享到:
评论

相关推荐

    java集合体系结构完结篇-Map集合

    java集合体系结构完结篇-Map集合

    Java-Java集合体系-List-Set

    Java-Java集合体系-List-Set 内容概要:总结了Java集体体系中的三大集合接口LIst、Set、Map,本文对LIst、Set做出了详细、简要的分析,没有冗长的文章,全是干货,下载即用,其中涉及了其底层实现,面试题必备。 ...

    java集合体系思维脑图

    java集合体系思维脑图,主要介绍了map、conllection、juc集合

    实验05 Java集合.doc

    掌握集合的概念、体系结构、分类及使用场景 2)了解Set接口及主要实现类(HashSet、TreeSet) 3)了解List接口及主要实现类(ArrayList、LinkedList、Vector) 4)了解Map接口及主要实现类(HashMap、TreeMap、...

    【Java】Java集合框架思维导图。

    xmind格式的Java集合框架学习导图,包括Collection接口/Map接口以及具体实现类。 同样包含大厂面试题,也在导图中有所体现。 能学到什么: 更加成体系的知识框架,更加全面的、系统的知识。 思维导图: 思维导图具有...

    JAVA–集合

    集合按照其存储结构可以分为两大类,单列集合java.util.Collection、双列集合java.util.Map 一、Collection Collection集合框架的体系 Collection常用功能 1.public boolean add(E e):把给定的对象添加到集合中 2....

    集合xmind整理(分为List、Set、Queue和Map四种体系)

    集合的xmind整理图。Java集合大致可分为List、Set、Queue和Map四种体系.List:代表有序、重复的集合。 Set:代表无序、不可重复的集合。 Map:则代表具有映射关系的集合。

    Java 基础核心总结 +经典算法大全.rar

    -、Iterator Iterable ListIterator 二、Map 和 Collection 接口Map 集合体系详解 HashMap LinkedHashMap TreeMap WeakHashMap Hashtable Collection 集合体系详解 Set 接口 AbstractSet 抽象类SortedSet 接口...

    Java集合

    Java的集合类是一种特别有用的工具类,它可以用于存储数量不等的多个对象,并可以实现常用数据结构,如栈,队列等,除此之外,Java集合还可用于保存具有映射关系的关联数组。 Java的集合大致上可分为:Set,List和...

    超全Java集合框架讲解.md

    - Map 集合体系详解 - HashMap - LinkedHashMap - TreeMap - WeakHashMap - Hashtable - Collection 集合体系详解 - Set 接口 - AbstractSet 抽象类 - SortedSet 接口 - HashSet - LinkedHashSet - ...

    JAVA集合框架

    集合框架是一个统一的架构,负责保存、装载数据...JAVA结合框架可以分为set、list、map、queue四大体系,其中set代表无序不可重复的集合;list代表有序、可重复的集合;map代表具有映射关系的集合;queue代表队列集合。

    java笔记整理(超详细) java笔记整理(超详细)

    Java集合可以分为Collection和Map两种体系: Collection接口: ​ List:元素有序,可重复的集合 ​ ArrayList: 底层数组实现,有利于随机访问get ​ LinkedList:底层是链表,有利于频繁的插入、删除操作(ArrayList删除和...

    毕业就业-刷题库Java面试题大全(2021年-2022年).rar

    a面试大全2021是一套最新Java面试必问合集,这本面试手册包含了Java基础、Java集合、JVM、Spring、Spring Boot、Spring Cloud、Mysql、Redis、RabbitMQ、Dubbo、Netty、分布式及架构设计等方面的技术点。内容难度...

    实验七:Java集合与泛型

    本次实验掌握了集合的概念、体系结构、分类及使用场景,了解了Set接口及主要实现类(HashSet、TreeSet),了解了解List接口及主要实现类(ArrayList、LinkedList、Vector),掌握ArrayList的使用及其与Vector的区别,...

    JAVA基础课程讲义

    第一个JAVA程序的总结和提升 20 常用Java开发工具 20 常用dos命令 21 本章笔试作业 21 本章上机操作 21 第二章(1) 编程的基本概念 22 注释 22 标识符 22 关键字/保留字 23 变量(variable) 24 常量(Constant) 25 命名...

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    HIBERNATE - 符合Java习惯的关系数据库持久化 Hibernate参考文档 3.2 -------------------------------------------------------------------------------- 目录 前言 1. 翻译说明 2. 版权声明 1. Hibernate...

    新版java教程 全套javase零基础到高级视频教程小白自学编程下载地址

    ,重点讲解Collection:集合框架体系List/Set/Map多种 实现和API ·玩转集合框架迭代器和HashCode和Equals重新排序 实战 ·实战teratori迭代器和自定义Comparable:排序接口 ·玩转ava操作文件File类常用操作 ·案例...

    集合以及其相关方法介绍.txt

    集合的分支体系 Collection Map 存储都value 存储的是key - value 键、值 List set 有序可重复 无序无重复 key是无序无重复的 value 无序可重复 序:顺序的意思,向集合里面放进去的顺序和...

    Java语音学习,基础教程

    学习集合:理解Java中的Collection、泛型、List、Set、Collections、Map和HashMap等概念和用法。 掌握异常处理:了解Java的异常体系、异常分类,学会声明、抛出和捕获异常,并自定义异常。 初步掌握多线程:理解线程...

    java初学者必看

    最近正在学习Java,也买了很多的有关Java方面的书籍,其中发现《跟我学Java》这本书,都的很不错啊,所以顺便拿电脑把这本书的目录敲了下来,与大家分享。尤其是那些和我一样初学Java的朋友们,看看哪一节对你有用,...

Global site tag (gtag.js) - Google Analytics