`
bolange
  • 浏览: 27090 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

集合框架——Map

    博客分类:
  • Java
阅读更多

      Map集合为映射类型,映射与集和列表有明显的区别,映射中的每个对象都是成对存在的。映射中存储的每个对象都有一个相应的键(Key)对象,在检索对象时必须通过相应的键对象来获取值(value)对象,类似于在字典中查找单词一样,因此要求键对象必须是惟一的。键对象还决定了存储对象在映射中的存储位置,但并不是键对象本身决定的,需要通过一种散列技术进行处理,从而产生一个被称作散列码的整数值,散列码通常用作一个偏置量,该偏置量是相对于分配给映射的内存区域的起始位置的,由此来确定存储对象在映射中的存储位置。理想情况下,通过散列技术得到的散列码应该是在给定范围内均匀分布的整数值,并且每个键对象都应该得到不同的散列码。

1. Map集合的用法 
      Map集合包括Map接口以及Map接口的所有实现类。由Map接口提供用来操作集合的常用方法如下表5所示:



      Map接口的常用实现类有HashMap和TreeMap,HashMap类通过哈希码对其内部的映射关系进行快速查找,而TreeMap类中的映射关系存在一定的顺序,如果希望在遍历集合时是有序的,应该使用由TreeMap类实现的Map集合,否则建议使用由HashMap类实现的Map集合,因为由HashMap类实现的Map集合对于添加和删除映射关系更高效。
Map集合允许值对象为null,并且没有个数限制,因此当get()方法的返回值为null时,可能有两种情况,一种是在集合中没有该键对象,另一种是该键对象没有映射任何值对象,即值对象为null。因此,在Map集合中不应该利用get()方法来判断是否存在某个键,而应该利用containsKey()方法来判断
例如:
源文件:TestMap.java

Java代码 复制代码
  1. import java.util.*;   
  2. public class TestMap{   
  3.     public static void main(String args[]){   
  4.         Map<Integer,String> map = new HashMap<Integer,String>();   
  5.         System.out.println("map集合是否为空:"+map.isEmpty());   
  6.         map.put(22015,null);   
  7.         System.out.println("map集合是否为空:"+map.isEmpty());   
  8.         map.put(22016,"马先生");   
  9.         System.out.println("map集合是否为空:"+map.isEmpty());   
  10.            
  11.         System.out.println("get()方法的返回结果:");   
  12.         System.out.print(map.get(22015));   
  13.         System.out.print("  "+map.get(22016));   
  14.         System.out.println("    "+map.get(22017));   
  15.   
  16.         System.out.println("containsKey()方法的返回结果:");   
  17.         System.out.print(map.containsKey(22015));   
  18.         System.out.print("  "+map.containsKey(22016));   
  19.         System.out.println("    "+map.containsKey(22017));   
  20.   
  21.         System.out.println("map集合中映射的个数:"+map.size());   
  22.         map.remove(22015);   
  23.         System.out.println("map集合中映射的个数:"+map.size());   
  24.     }   
  25. }  


程序的运行结果如下:
map集合是否为空:true
map集合是否为空:false
map集合是否为空:false
get()方法的返回结果:
null    马先生  null
containsKey()方法的返回结果:
true    true    false
map集合中映射的个数:2
map集合中映射的个数:1


2. 使用HashMap类
HashMap类实现了Map接口,由HashMap类实现的Map集合允许以null作为键对象,但是因为键对象不可以重复,所以这样的键对象只能有一个。如果经常需要添加、删除和定位映射关系,建议利用HashMap类实现Map集合,不过在遍历集合时得到的映射关系是无序的。
在使用由HashMap类实现的Map集合时,如果想有效地使用,就必须重写作为主键对象类的hashCode()方法,在重写hashCode()方法时,有两条基本原则:
● 不唯一原则:不必为每个对象生成一个惟一的哈希码,只要通过hashCode()方法生成的哈希码,利用get()方法能够得到利用put()方法添加的映射关系即可。
● 分散原则:生成哈希码的算法应尽量使哈希码的值分散一些,不要将很多哈希码值都集中在一个范围内,这样有利于提高由HashMap类实现的Map集合的性能。
例如:
源文件:PK_person.java

Java代码 复制代码
  1. public class PK_person{   
  2.     private String prefix;   
  3.     private long number;   
  4.     public String setPrefix(){   
  5.         return prefix;   
  6.     }   
  7.     public void setPrefix(String prefix){   
  8.         this.prefix = prefix;   
  9.     }   
  10.     public long getNumber(){   
  11.         return number;   
  12.     }   
  13.     public void setNumber(long number){   
  14.         this.number = number;   
  15.     }   
  16.     public String getPK(){   
  17.         return this.prefix+"_"+this.number;   
  18.     }   
  19.     public void setPK(String pk){   
  20.         int i = pk.indexOf("_");   
  21.         this.prefix = pk.substring(0,i);   
  22.         this.number = new Integer(pk.substring(i));   
  23.     }   
  24. }  


源文件:Person.java

Java代码 复制代码
  1. public class Person{   
  2.     private String name;   
  3.     private PK_person number;   
  4.     public Person(PK_person number,String name){   
  5.         this.number = number;   
  6.         this.name = name;   
  7.     }   
  8.     public String getName(){   
  9.         return name;   
  10.     }   
  11.     public void setName(String name){   
  12.         this.name = name;   
  13.     }   
  14.     public PK_person getNumber(){   
  15.         return number;   
  16.     }   
  17.     public void setNumber(PK_person number){   
  18.         this.number = number;   
  19.     }   
  20. }  


源文件:TestMap.java

Java代码 复制代码
  1. import java.util.*;   
  2. public class TestMap{   
  3.     public static void main(String args[]){   
  4.         Map<PK_person,Person> map = new HashMap<PK_person,Person>();   
  5.         PK_person pk_person1 = new PK_person();   
  6.         pk_person1.setPrefix("MR");   
  7.         pk_person1.setNumber(22015);   
  8.         map.put(pk_person1,new Person(pk_person1,"马先生"));   
  9.         PK_person pk_person2 = new PK_person();   
  10.         pk_person2.setPrefix("MR");   
  11.         pk_person2.setNumber(22015);   
  12.         Person person = map.get(pk_person2);   
  13.         if(person == null){   
  14.             System.out.println("该键对象不存在!");   
  15.         }   
  16.         else{   
  17.             System.out.println(person.getNumber().getNumber()+" "+person.getName());   
  18.         }   
  19.     }   
  20. }  


程序的运行结果如下: 
      该键对象不存在! 
      无论执行多少次,输出的信息都为“该键对象不存在!”,即在集合中不存在该键对象。这是因为没有重写java.lang.Object()类中的hashCode()和equals()方法,equals()方法默认比较两个对象的地址,因此即使这两个键对象的内容完全相同,也不认为是同一个对象,重写后的hashCode()和equals()方法的完整代码如下:

Java代码 复制代码
  1. public int hashCode(){//重写hashCode()方法   
  2.     return (int)(number + prefix.hashCode());   
  3. }   
  4. public boolean equals(Object obj){//重写equals()方法   
  5.     if(obj == null){   
  6.         return false;   
  7.     }   
  8.     if(getClass()!=obj.getClass()){   
  9.         return false;   
  10.     }   
  11.     if(this == obj){   
  12.         return true;   
  13.     }   
  14.     final PK_person other = (PK_person)obj;   
  15.     if(this.hashCode()!=other.hashCode()){   
  16.         return false;   
  17.     }   
  18.     return true;   
  19. }  


重写PK_person类中的hashCode()和equals()方法后,再次执行程序,结果如下:
2015   马先生


3. 使用TreeMap类 
      TreeMap类不仅实现了Map接口,还实现了Map接口的子接口java.util.SortedMap。由TreeMap类实现的Map集合不允许键对象为null,因为集合中的映射关系是根据键对象按照一定顺序排列的,TreeMap类通过实现SortedMap接口得到的方法如下表6所示:



在添加、删除和定位映射关系上,TreeMap类要比HashMap类的性能差一些,但是其中的映射关系具有一定的顺序,如果不需要一个有序的集合,则建议使用HashMap类;如果需要进行有序的遍历输出,则建议使用TreeMap类,在这种情况下,可以先使用由HashMap类实现的Map集合,在需要顺序输出时,在利用现有的HashMap类的实例创建一个具有完全相同映射关系的TreeMap类型的实例。
例如:
源文件:Person.java

Java代码 复制代码
  1. public class Person{   
  2.     private String name;   
  3.     private long id_card;   
  4.     public Person(String name,long id_card){   
  5.         this.id_card = id_card;   
  6.         this.name = name;   
  7.     }   
  8.     public String getName(){   
  9.         return name;   
  10.     }   
  11.     public void setName(String name){   
  12.         this.name = name;   
  13.     }   
  14.     public long getId_card(){   
  15.         return id_card;   
  16.     }   
  17.     public void setId_card(long id_card){   
  18.         this.id_card = id_card;   
  19.     }   
  20. }  


源文件:TestMap.java

Java代码 复制代码
  1. import java.util.*;   
  2. public class TestMap{   
  3.     public static void main(String args[]){   
  4.         Person p1 = new Person("马先生",22015);   
  5.         Person p2 = new Person("李小姐",22018);   
  6.         Person p3 = new Person("马先生",22016);   
  7.         Map<Number,Person> map = new HashMap<Number,Person>();   
  8.         map.put(22015,p1);   
  9.         map.put(22018,p2);   
  10.         map.put(22016,p3);   
  11.         System.out.println("由HashMap类实现的Map集合,无序:");   
  12.         Iterator<Number> it1 = map.keySet().iterator();   
  13.         while(it1.hasNext()){   
  14.             Person person = map.get(it1.next());   
  15.             System.out.println(person.getId_card()+"    "+person.getName());   
  16.         }   
  17.         System.out.println("由TreeMap类实现的Map集合,键对象升序:");   
  18.         TreeMap<Number,Person> treeMap1 = new TreeMap<Number,Person>();   
  19.         treeMap1.putAll(map);   
  20.         Iterator<Number> it2 = treeMap1.keySet().iterator();   
  21.         while(it2.hasNext()){   
  22.             Person person = treeMap1.get(it2.next());   
  23.             System.out.println(person.getId_card()+"    "+person.getName());   
  24.         }   
  25.         System.out.println("由TreeMap类实现的Map集合,键对象降序:");   
  26.         TreeMap<Number,Person> treeMap2 = new TreeMap<Number,Person>(Collections.reverseOrder());   
  27.         treeMap2.putAll(map);   
  28.         Iterator<Number> it3 = treeMap2.keySet().iterator();   
  29.         while(it3.hasNext()){   
  30.             Person person = treeMap2.get(it3.next());   
  31.             System.out.println(person.getId_card()+"    "+person.getName());   
  32.         }   
  33.     }   
  34. }  


程序的运行结果如下:
由HashMap类实现的Map集合,无序:
22016   马先生
22018   李小姐
22015   马先生
由TreeMap类实现的Map集合,键对象升序:
22015   马先生
22016   马先生
22018   李小姐
由TreeMap类实现的Map集合,键对象降序:
22018   李小姐
22016   马先生
22015   马先生

分享到:
评论

相关推荐

    Java面试题资料,包含核心知识,消息队列,大数据等

    这份资料不仅应该触及Java的基石——例如JVM的工作原理、内存模型、垃圾回收机制,以及Java的集合框架中的核心接口与实现类,如List、Set、Map等,更应对Java的异常处理机制有深入的剖析 此外,考虑到Java技术的...

    Java SE实践教程 源代码 下载

    第3章 当一个变成多个——集合框架的基本概念 53 .3.1 讲解 54 3.1.1 集合概述 54 3.1.2 Collection接口 54 3.1.3 泛型(Generics) 56 3.1.4 Map接口 57 3.2 练习 59 3.2.1 创建课程管理系统 59 3.3 小结 ...

    Java SE实践教程 pdf格式电子书 下载(一) 更新

    第3章 当一个变成多个——集合框架的基本概念 53 .3.1 讲解 54 3.1.1 集合概述 54 3.1.2 Collection接口 54 3.1.3 泛型(Generics) 56 3.1.4 Map接口 57 3.2 练习 59 3.2.1 创建课程管理系统 59 3.3 小结 ...

    Java SE实践教程 pdf格式电子书 下载(四) 更新

    第3章 当一个变成多个——集合框架的基本概念 53 .3.1 讲解 54 3.1.1 集合概述 54 3.1.2 Collection接口 54 3.1.3 泛型(Generics) 56 3.1.4 Map接口 57 3.2 练习 59 3.2.1 创建课程管理系统 59 3.3 小结 ...

    Android 初学中阶高阶书籍_集合打包2

    出,Android真机开发教程,Android中文翻译组——Android中文API合集(4), bluetooth 蓝牙,Google_Map_API谷歌地 图,Android的XML解析,牛人Android提高篇,手把手教你用Android开发新浪微博客户端

    Android 初学中阶高阶书籍_集合打包3

    出,Android真机开发教程,Android中文翻译组——Android中文API合集(4), bluetooth 蓝牙,Google_Map_API谷歌地 图,Android的XML解析,牛人Android提高篇,手把手教你用Android开发新浪微博客户端

    2020世界信息安全大会演示PPT集合.zip

    2020世界信息安全大会演示PPT集合,共大家参考学习,包括: 基于OPC DA协议C2攻击链; 安全运营体系建设; 大型企业基础架构安全; 工控设备系统安全实践; 攻防技术趋势和企业威胁猎捕能力建设实践; 合规视角下...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    3.4 小结:基本数据类型—— Java中一切数据和运算的基础 63 3.5 习题 65 第4章 Java中的程序执行流程 67 教学视频:1小时57分钟 4.1 顺序执行 67 4.2 使用if-else让程序懂得判断 68 4.2.1 if语句 68 4.2.2 ...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    3.4 小结:基本数据类型—— Java中一切数据和运算的基础 63 3.5 习题 65 第4章 Java中的程序执行流程 67 教学视频:1小时57分钟 4.1 顺序执行 67 4.2 使用if-else让程序懂得判断 68 4.2.1 if语句 68 4.2.2 ...

    javaSE代码实例

    第14章 集合框架——强大的对象管理器 270 14.1 Object类——所有类的超类 270 14.1.1 toString方法的重写 270 14.1.2 equals方法的意义 271 14.1.3 hashCode方法的意义 272 14.2 重写equals与hashCode...

    疯狂的java讲义源码-gal-practice-lesson:gal实践课

    集合的四个基本操作,并解释何时使用每个操作。 预计长度 任务 分钟 操作说明 25-40 活动与挑战 25-45 结语 10 示例学生课程 —— —— 示例活动 (未完成) 示例牌组 没有可用的。 示例讲师课程计划 框架 到目前...

    android精品源码

    Android中文翻译组——Android中文API合集(4).pdf Android内存泄露调试.pdf android写的google map api 应用.zip Android实现GPS定位.pdf Android应用框架原理与程序设计36技.pdf Android摄像头的应用.pdf 还有很...

    Google_MapReduce中文版-系统架构

    一个Map函数处理一个基于key/value pair的数据集合,输出中间的基于key/value pair的数据集合;然 后再创建一个Reduce函数用来合并所有的具有相同中间key值的中间value值。现实世界中有很多满足 上述处理模型的例子...

    【白雪红叶】JAVA学习技术栈梳理思维导图.xmind

    UMPAY——编码规范 日志规范 异常规范 网络 协议 TCP/IP HTTP hession file HTTPS 负载均衡 容器 JBOSS tomcat resin jetty 容灾 日志框架 开源框架 slf4j 框架实现 log4j logback commong ...

    Java JDK实例宝典

    12 对Map排序 4. 13 Properties属性文件 第5章 字符串 5. 1 使用String 5. 2 基本数据类型与字符串的转化 5. 3 判断Java标识符 5. 4 使用StringBuffer 5. 5 IP地址转化成整数 5. 6...

    Python编程入门经典

    3.3.5 处理集合 43 3.4 本章小结 44 3.5 习题 44 第Ⅱ部分 Python语言和标准库 第4章 做出决策 49 4.1 比较两个值是否相等 49 4.2 比较两个值是否不相等 51 4.3 比较两个值的大小 51 4.4 对真值和假值取反 53 4.5 ...

    深入浅出ES6 简体中文

    迭代器Iterator、生成器Generators、不定参数Rest、默认参数Default、解构Destructuring、生成器Generator、代理Proxy,以及几种新类型:Set、Map、WeakSet、WeakMap、集合Collection。 以上提及的新特性只是其中的...

    BigDataAnalysis_Exp1:实时大数据分析_A-Priori算法实验

    取支持度阈值s =185,用A-Priori算法在Map-Reduce框架下提取其中的最大频繁项集Lk。 附件:某超市数据集basketdata.xls 二、实验设计(原理分析及流程) 该算法的基本思想是:首先找出所有的频集,这些项集出现的...

    Cocos2D-X游戏开发技术精解

    第3章 引擎的核心——渲染框架 49 3.1 基本框架 50 3.1.1 引擎的位置 50 3.1.2 根源种子 51 3.1.3 子类结构 57 3.2 渲染框架 57 3.2.1 框架结构 58 3.2.2 摄像机类(CCCamera) 59 3.2.3 导演类(CCDirector...

Global site tag (gtag.js) - Google Analytics