zoukankan      html  css  js  c++  java
  • Java——(七)Map之HashMap和Hashtable实现类

     ------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

    Map

      Map用于具有映射关系的数据,因此Map集合里保存着两组值,一组值用于保存Map里的key,

    另一组值用于保存Map里的value,key和value都可以是任何引用类型的数据。Map的key不允许

    重复,即同一个Map对象的任何两个key通过equals()方法比较总是返回false。

      Set与Map之间的关系非常密切。虽然Map中放的元素是key—value对,Set集合中放的元素是

    单个对象,但如果把key—value对中的value当成key的附庸:key在哪,value就在哪。这样就可以

    像对待Set一样对待Map了。Map提供了一个Entry内部类来封装key—value对,而计算Entry存储时

    则只考虑Entry封装的key。当Map中的所有元素value都为null时,就实现了Set集合。

      Map接口中定义了如下常用的方法:

    1)void clear():删除该Map对象中的所有key—value对。

    2)boolean containsKey(Object key):查询Map中是否包含指定的key,如果包含则返回true。

    3)boolean containsValue(Object value):查询Map中是否包含一个或多个value,如果包含则返回true。

    4)Set entrySet():返回Map中包含的key—value对所组成的Set集合,每个集合元素都是Map。Entry对象。

    5)Object get(Object key):返回指定key所对应的value;如果此Map中不包含该key,则返回null。
    6)boolean isEmpty():查询该Map是否为空(即不包含任何key—value对),如果为空,则返回true。
    7)Set keySet():返回该Map中所有key组成的Set集合。

    8)Object put(Object key, Object value):添加一个key—value对,如果当前Map中已有一个与该key相等的

    key—value对,则新的key—value会覆盖原来的key—value对。

    9)void putAll(Map m):将指定Map中的key—value对复制到本Map中。

    10)Object remove(Object o):删除指定key所对应的key—value对,返回被删除key所关联的value,如果该key不存

    在,则返回null。

    11)int size():返回该Map里的key—value对的个数。

    12)Collection values():返回该Map里所有value组成的Collection。

      Map接口提供了大量的实现类,典型实现如HashMap和Hashtable等、HashMap的子类LinkedHashMap,还有

    SortedMap子接口及该接口的实现类TreeMap,以及WeakHashMap、IdentityHashMap等。下面将详细介绍Map

    接口实现类。

      Map中包含一个内部类Entry,该类封装了一个key—value对。Entry包含如下三个方法:

      1)Object getKey():返回该Entry里包含的key值。

      2)Object getValue():返回该Entry里包含的value值。

      3)Object setValue(V value):设置该Entry了包含的value值,并返回新设置的value值。

    1.HashMap和Hashtable实现类

      HashMap和Hashtable都是Map接口的典型实现类,它们之间的关系完全类似于ArrayList和Vector的关系:Hashtable

    是一个古老的Map实现类。

      HashMap和Hashtable存在典型区别。

      1)Hashtable是一个线程安全的Map实现,但hashMap是线程不安全的实现,所以HashMap比Hashtable的性能高一点

    ;但如果有多个线程访问同一个Map对象时,使用Hashtable实现类会更好。

      2)Hashtable不允许使用null作为key和value,如果试图把null值放入Hashtable中,将会引发NullPointerException

    异常;但HashMap可以使用null作为key和value。

      下面程序示范了用null值作为HashMap的key和value的情况。

     1 import java.util.HashMap;
     2 
     3 
     4 public class NullInHashMap {
     5 
     6     public static void main(String[] args) {
     7 
     8         HashMap hMap = new HashMap<>();
     9         //试图将两个key为null值的key—value对放入HashMap中
    10         hMap.put(null, null);
    11         hMap.put(null, null);
    12         //将一个value为null值的key—value对放入HashMap中
    13         hMap.put("a", null);
    14         System.out.println(hMap);
    15     }
    16 
    17 }

    运行结果:

    {null=null, a=null}

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

    对的顺序。类似于HashSet,HashMap、Hashtable判断两个key相等的标准也是:两个key通过

    equals()方法比较返回true,两个key的hashCode值也相等。此外,HashMap、Hashtable中还包

    含指定的value。只有两个对象通过equals()方法比较返回true即可。下面程序示范了Hashtable判断

    两个key相等的标准和两个value相等的标准。

     1 import java.util.Hashtable;
     2 
     3 class A {
     4     int count;
     5 
     6     public A(int count) {
     7         this.count = count;
     8     }
     9 
    10     @Override
    11     public boolean equals(Object obj) {
    12 
    13         if (obj == this) {
    14             return true;
    15         }
    16         if (obj != null && obj.getClass() == A.class) {
    17             A a = (A) obj;
    18             return this.count == a.count;
    19         }
    20         return false;
    21     }
    22 
    23     @Override
    24     public int hashCode() {
    25         return this.count;
    26     }
    27 }
    28 
    29 class B {
    30     @Override
    31     public boolean equals(Object obj) {
    32 
    33         return true;
    34     }
    35 }
    36 
    37 public class HashtableTest {
    38 
    39     public static void main(String[] args) {
    40 
    41         Hashtable ht = new Hashtable<>();
    42         ht.put(new A(60), "黑马程序员");
    43         ht.put(new A(52), "传智播客");
    44         ht.put(new A(78), "CSDN");
    45         ht.put(new A(60), new B());
    46         System.out.println(ht);
    47         /*只要两个对象通过equals()方法比较返回true,Hashtable就认为
    48          * 它们是相等的value,由于Hashtable中有一个B对象,它与任何
    49          * 对象通过equals()方法比较都相等,所以下面输出true*/
    50         System.out.println(ht.containsValue("测试字符串"));
    51         /*只要两个A对象的count对象相等,它们通过equals()方法比较返回
    52          * true,且hashCode值相等,Hashtable即认为它们是相等的key,
    53          * 所以输出true*/
    54         System.out.println(ht.containsKey(new A(52)));
    55         //删除最后一个key—value对
    56         ht.remove(new A(78));
    57         //通过返回Hashtable返回的所有key组成的Set集合
    58         //从而遍历Hashtable的每个key—value对
    59         for (Object key : ht.keySet()) {
    60             System.out.println(key + "---->");
    61             System.out.println(ht.get(key) + "
    ");
    62         }
    63     }
    64 
    65 }

    运行结果:

    {A@34=传智播客, A@3c=B@592fa617, A@4e=CSDN}
    true
    true
    A@34---->
    传智播客
    
    A@3c---->
    B@592fa617

      上面程序定义了A类和B类,其中A类判断两个A对象相等的标准是count实例变量:只要两个A对

    象的count变量相等,则通过equals()方法比较它们返回true,它们的hashCode值也相等;而B对象

    则可以与任何对象相等。

      与HashSet类似,如果使用可变对象作为HashMap、Hashtable的key,并且程序修改了作为key

    的可变对象,则也可能出现于HashSet类似的情况:程序再也无法准确访问到Map中被修改过的key。

    以下程序示范了上述情况。

     1 import java.util.Hashtable;
     2 import java.util.Iterator;
     3 
     4 class A {
     5     int count;
     6 
     7     public A(int count) {
     8         this.count = count;
     9     }
    10 
    11     @Override
    12     public boolean equals(Object obj) {
    13 
    14         if (obj == this) {
    15             return true;
    16         }
    17         if (obj != null && obj.getClass() == A.class) {
    18             A a = (A) obj;
    19             return this.count == a.count;
    20         }
    21         return false;
    22     }
    23 
    24     @Override
    25     public int hashCode() {
    26         return this.count;
    27     }
    28 }
    29 
    30 public class HashtableErrorTest {
    31 
    32     public static void main(String[] args) {
    33 
    34         Hashtable htHashtable  = new Hashtable<>();
    35         htHashtable.put(new A(60), "黑马程序员");
    36         htHashtable.put(new A(52), "传智播客");
    37         //获取Hashtable的key Set集合对应的Iterator迭代器
    38         Iterator iterator = htHashtable.keySet().iterator();
    39         System.out.println(htHashtable);
    40         //取出Map中第一个key
    41         A first = (A) iterator.next();
    42         first.count = 60;
    43         System.out.println(htHashtable);
    44         //只能删除没有修改过的key所对应的key—value对
    45         htHashtable.remove(new A(60));
    46         System.out.println(htHashtable);
    47         System.out.println(htHashtable.get(new A(60)));
    48         System.out.println(htHashtable.get(new A(52)));
    49     }
    50 
    51 }

    运行结果:

    {A@34=传智播客, A@3c=黑马程序员}
    {A@3c=传智播客, A@3c=黑马程序员}
    {A@3c=传智播客}
    null
    null
  • 相关阅读:
    vbscript 语言通过序列和ADODB实现取号不重复
    arcgisserver成功发布服务后,浏览服务,无地图显示
    GUID的获取
    EasyUi 表格自适应宽度
    接口隔离原则
    依赖倒置原则
    开放封闭原则
    单一职责原则
    python-函数基础
    python -流程控制
  • 原文地址:https://www.cnblogs.com/xiongxuesong/p/4567886.html
Copyright © 2011-2022 走看看