zoukankan      html  css  js  c++  java
  • java中HashMap的用法

    重点介绍HashMap。首先介绍一下什么是Map。在数组中我们是通过数组下标来对其内容索引的,而在Map中我们通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value。在下文中会有例子具体说明。

      再来看看HashMap和TreeMap有什么区别。HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。

     import java.util.Map;    
    import java.util.HashMap;    
    import java.util.Set;    
    import java.util.HashSet;    
    import java.util.Iterator;    
    import java.util.Hashtable;    
    import java.util.TreeMap;    
    class  HashMaps    
    {    
           public static void main(String[] args)     
          {    
                Map map=new HashMap();                
                map.put("a", "aaa");    
                map.put("b", "bbb");    
                map.put("c", "ccc");    
                map.put("d", "ddd");    
                   
                Iterator iterator = map.keySet().iterator();                
                while (iterator.hasNext()) {    
                 Object key = iterator.next();    
                 System.out.println("map.get(key) is :"+map.get(key));    
                }           
                    
                    
                    
                Hashtable tab=new Hashtable();                
                tab.put("a", "aaa");    
                tab.put("b", "bbb");    
                tab.put("c", "ccc");    
                tab.put("d", "ddd");    
                Iterator iterator_1 = tab.keySet().iterator();    
                while (iterator_1.hasNext()) {    
                 Object key = iterator_1.next();    
                 System.out.println("tab.get(key) is :"+tab.get(key));    
                }             
                    
                TreeMap tmp=new TreeMap();                
                tmp.put("a", "aaa");    
                tmp.put("b", "bbb");    
                tmp.put("c", "ccc");    
                tmp.put("d", "ddd");    
                Iterator iterator_2 = tmp.keySet().iterator();    
                while (iterator_2.hasNext()) {    
                 Object key = iterator_2.next();    
                 System.out.println("tmp.get(key) is :"+tmp.get(key));    
                }             
                              
                 
           }    
             
    }    
    

    执行完后,果然是这样的(hashmap是没有顺序的,而treemap则是按顺序排列的哦!!)

    下面就要进入本文的主题了。先举个例子说明一下怎样使用HashMap:

    import java.util.*;     
       
    public class Exp1 {    
         public static void main(String[] args){    
              HashMap h1=new HashMap();    
              Random r1=new Random();        
              for(int i=0;i<1000;i++){    
                   Integer t=new Integer(r1.nextInt(20));    
                   if(h1.containsKey(t))    
                        ((Ctime)h1.get(t)).count++;    
                   else   
                        h1.put(t, new Ctime());    
              }    
              System.out.println(h1);    
         }    
    }    
       
    class Ctime{    
         int count=1;    
         public String toString(){    
              return Integer.toString(count);    
         }    
    }   
    

    在HashMap中通过get()来获取value,通过put()来插入value,ContainsKey()则用来检验对象是否已经存在。可以看出,和ArrayList的操作相比,HashMap除了通过key索引其内容之外,别的方面差异并不大。

       前面介绍了,HashMap是基于HashCode的,在所有对象的超类Object中有一个HashCode()方法,但是它和equals方法一样,并不能适用于所有的情况,这样我们就需要重写自己的HashCode()方法。下面就举这样一个例子:

    import java.util.*;     
       
    public class Exp2 {    
         public static void main(String[] args){    
              HashMap h2=new HashMap();    
              for(int i=0;i<10;i++)    
                   h2.put(new Element(i), new Figureout());    
              System.out.println("h2:");    
              System.out.println("Get the result for Element:");    
              Element test=new Element(5);    
              if(h2.containsKey(test))    
                   System.out.println((Figureout)h2.get(test));    
              else   
                   System.out.println("Not found");    
         }    
    }    
       
    class Element{    
         int number;    
         public Element(int n){    
              number=n;    
         }     
    }    
       
    class Figureout{    
         Random r=new Random();    
         boolean possible=r.nextDouble()>0.5;    
         public String toString(){    
              if(possible)    
                   return "OK!";    
              else   
                   return "Impossible!";    
         }    
    }   
    

    在这个例子中,Element用来索引对象Figureout,也即Element为key,Figureout为value。在Figureout中随机生成一个浮点数,如果它比0.5大,打印"OK!",否则打印"Impossible!"。之后查看Element(5)对应的Figureout结果如何。

    结果却发现,无论你运行多少次,得到的结果都是"Not found"。也就是说索引Element(5)并不在HashMap中。这怎么可能呢?

    原因得慢慢来说:Element的HashCode方法继承自Object,而Object中的HashCode方法返回的HashCode对应于当前的地址,也就是说对于不同的对象,即使它们的内容完全相同,用HashCode()返回的值也会不同。这样实际上违背了我们的意图。因为我们在使用HashMap时,希望利用相同内容的对象索引得到相同的目标对象,这就需要HashCode()在此时能够返回相同的值。在上面的例子中,我们期望new Element(i) (i=5)与 Element test=new Element(5)是相同的,而实际上这是两个不同的对象,尽管它们的内容相同,但它们在内存中的地址不同。因此很自然的,上面的程序得不到我们设想的结果。下面对Element类更改如下:

    class Element{    
         int number;    
         public Element(int n){    
              number=n;    
         }     
         public int hashCode(){    
              return number;    
         }    
         public boolean equals(Object o){    
              return (o instanceof Element) && (number==((Element)o).number);    
         }    
    }   
    

       在这里Element覆盖了Object中的hashCode()和equals()方法。覆盖hashCode()使其以number的值作为hashcode返回,这样对于相同内容的对象来说它们的hashcode也就相同了。而覆盖equals()是为了在HashMap判断两个key是否相等时使结果有意义(有关重写equals()的内容可以参考我的另一篇文章《重新编写Object类中的方法 》)。修改后的程序运行结果如下:

    h2:
    Get the result for Element:
    Impossible!

    请记住:如果你想有效的使用HashMap,你就必须重写在其的HashCode()。还有两条重写HashCode()的原则:

       不必对每个不同的对象都产生一个唯一的hashcode,只要你的HashCode方法使get()能够得到put()放进去的内容就可以了。即"不为一原则"。 生成hashcode的算法尽量使hashcode的值分散一些,不要很多hashcode都集中在一个范围内,这样有利于提高HashMap的性能。即"分散原则"。

  • 相关阅读:
    JeePlus:代码生成器
    JeePlus:API工具
    Java实现 洛谷 P1023 税收与补贴问题
    Java实现 洛谷 P1023 税收与补贴问题
    Java实现 洛谷 P1023 税收与补贴问题
    Java实现 洛谷 P1328 生活大爆炸版石头剪刀布
    Java实现 洛谷 P1328 生活大爆炸版石头剪刀布
    Java实现 洛谷 P1328 生活大爆炸版石头剪刀布
    Java实现 洛谷 P1328 生活大爆炸版石头剪刀布
    Java实现 洛谷 P1328 生活大爆炸版石头剪刀布
  • 原文地址:https://www.cnblogs.com/vofill/p/5256873.html
Copyright © 2011-2022 走看看