• Java中的集合框架-Map


      前两篇《Java中的集合框架-Commection(一)》《Java中的集合框架-Commection(二)》把集合框架中的Collection开发常用知识点作了一下记录,从本篇开始,对集合框架里的另外一部分Map作一下记录。

    一,集合框架的Map接口

      Map与Collection不同之处在于它是以键值对来存储数据;

      Map比较常用的实现类有四个:HashTable,HashMap,LinkedHashMap,TreeMap;

      Map的方法也可以分为四类,增删改查,大致如下:

      新增的方法:

          put(k,v)  此方法将一对Key:Value形式的数据添加到容器中,并返回此Key所对应的旧值的结果(如果Key已存在的话),若此Key是一个新的Key则返回一个null

          put(Map)  此方法的作用是把一个Map中的元素复制到此Map中

      删除的方法:

          clear()  清除容器中的所有元素

          remove()  此方法移除一对Key:Value,返回的是被移除的键所对应的值

      修改的方法:

          put(k,v)  键相同,值不同便起到了修改的作用

      查询的方法:

          containsKey(key)  是否包含指定的Key,若包含则返回true

          containsValue(value)  是否包含指定的Value,若包含则返回true

          get(key)  返回指定的键所对应的值

          isEmpty()  查询Map是不是为空,若为空则返回true

          size()  返回Map中Key:Value的数量

          keySet()  返回Map中所有Key所组成的一个Set集合

          values()  返回Map中所有Value对应的Collection集合

          entrySet()  返回键值对所对应的Map.entry的Set集合

      其它的equals方法,hashcode方法便不再罗列。方法的使用还是到它的实现类中去演示,在此不作演示。

    二,HashTable与HashMap

      HashTable是1.0出现的,后来它被HashSet所取代;

      HashTable内部结构是哈希表,它是线程安全的,另外HashTable不可存储null键以及null值;

      HashMap功能与HashTable基本相同,只是它非线程安全,另外它可存储null健以及null值;

      虽然HashMap内部是哈希表的结构,但是它真正的存储结构是数组+链表的形式,当一个元素被put进来的时候,它会先计算该元素的hashcode,当hashcode冲突的时候,它会使用链表进行挂载;

      当HashMap存储null键和null值的时候,它会存储到数组下标0的位置,若该位置有元素存在则进行挂载。

      HashMap在存储自定义对象的时候和HashSet一样(其实HashSet里面维护的就是一个HashMap),也会先调用该元素的hashcode方法,当hashcode相同是再去调用该元素的equals方法去判断两个元素是否为同一个元素,若是同一个元素则修改其原来的值为新值并返回原来的值;若元素的hashcode不同,则直接判断为不同的元素进行存储;演示如下:

     1 public class Person {
     2     private String name;
     3     private int age;
     4 
     5     public Person(String name, int age) {
     6         this.name = name;
     7         this.age = age;
     8     }
     9 
    10     public String getName() {
    11         return name;
    12     }
    13 
    14     public void setName(String name) {
    15         this.name = name;
    16     }
    17 
    18     public int getAge() {
    19         return age;
    20     }
    21 
    22     public void setAge(int age) {
    23         this.age = age;
    24     }
    25 
    26 }
      主程序:
    1     private static void fun_demo2() {
    2         HashMap hm = new HashMap();
    3         hm.put(new Person("张三", 32), "程序员");
    4         hm.put(new Person("张三", 12), "项目经理");
    5         hm.put(new Person("王五", 22), "老板");
    6         System.out.println(hm);
    7     }

       程序运行结果:

            

      可见三个元素都被存储进去了,这个原因很好理解,每new出来一个Person,它的hashcode是不一样的,所以存储了三个元素。下面我们改一下Person类,重写一下hashcode和equals方法

     1 public class Person {
     2     private String name;
     3     private int age;
     4 
     5     public Person(String name, int age) {
     6         this.name = name;
     7         this.age = age;
     8     }
     9 
    10     public String getName() {
    11         return name;
    12     }
    13 
    14     public void setName(String name) {
    15         this.name = name;
    16     }
    17 
    18     public int getAge() {
    19         return age;
    20     }
    21 
    22     public void setAge(int age) {
    23         this.age = age;
    24     }
    25 
    26     @Override
    27     public int hashCode() {
    28         return this.getName().hashCode();
    29     }
    30 
    31     @Override
    32     public boolean equals(Object obj) {
    33         return true;
    34     }
    35 
    36 }

      程序运行结果:

            

      可见我们把hashcode直接返回Person的name的hashcode,由于Person对象有两个叫张三的,所以它会调用equals方法再进一步比较这两个对象是否为同一个元素,我们的equals方法又返回了true,它就认定这两个元素是同一个元素,所以拿第二个“张三”的Value值“项目经理”把第一个“张三”的Value值“程序员”给覆盖掉了。

      其它的关于HashMap的方法不再一一演示。

    三,LinkedHashMap

      LinkedHashMap与HashMap的区别是LinkedHashMap内部维护着一个所有元素的双向链表,它能保证存储进容器的元素与取出元素的顺序一致;请看以下操作:

     1     private static void fun_demo3() {
     2         HashMap lhm = new HashMap();
     3         lhm.put(2, "z");
     4         lhm.put(3, "a");
     5         lhm.put(1, "b");
     6         lhm.put(0, "z");
     7         lhm.put(null, "t");
     8         Iterator iterator = lhm.entrySet().iterator();
     9         while (iterator.hasNext()) {
    10             Map.Entry entry = (Entry) iterator.next();
    11             System.out.println(entry.getKey() + ":" + entry.getValue());
    12         }
    13     }

       程序运行结果:

            

      它对元素的Key进行了自然顺序的排序,之所以null元素在0元素的后面,就是因为null元素会自动存储到数组0的位置,若0的位置有了元素便进行链式存储进行挂载;

      我们把上面的程序的第一行改为LinkedHashMap lhm=new LinkedHashMap();则程序运行结果如下:

            
      可见和我们存储元素的位置是一样的。

    四,TreeMap

      TreeMap是基于二叉树的结构来存储数据的,它会按照键的自然顺序进行存储数据;

      当TreeMap存储自定义对象时,此对象需要实现Comparable接口并重写compareTo方法;

      也可接收一个Comparator比较器对象来实例化TreeMap;

      其操作方法与TreeSet相类似,便不再演示了(TreeSet内部便是TreeMap);

     

  • 相关阅读:
    数学中求余数问题
    点击事件后根据url保持相应导航高亮
    TP5和TP3.2的使用区别
    在已部署好的docker环境下配置nginx项目路径
    Tp5整理
    cookies、sessionStorage和localStorage的异同点
    CSS的长度单位
    Linux sed识别HTML标签
    css样式读取
    seller vue配置路径相对路径【组件 只写简单路径】
  • 原文地址:https://www.cnblogs.com/zw971084570/p/10125362.html
Copyright © 2020-2023  润新知